Android: доступ к Mapview внутри фрагмента с помощью ViewPager

Я использую View Pager для отображения трех представлений.

"Filter","Streets","Around"

Каждое представление определяется фрагментом.

ЧЕГО Я ХОЧУ: я хочу использовать Mapview внутри своего фрагмента фильтра.

ЧТО Я СДЕЛАЛ:

Я хочу использовать MapView внутри фрагмента фильтра, но не смог успешно запуститься. и Получение журнала ошибок:

android.view.InflateException: Binary XML file line #33: Error inflating class com.google.android.maps.MapView

Я также искал в сети и Stackoverflow об этой проблеме и нашел LINK и ССЫЛКА, но не удалось найти эту ссылку, связанную с моей проблемой, поскольку я использую фрагмент с ViewPager.

Я поставил свой код, как показано ниже.

Вот мой код для MainViewPager.java:

    package com.example.viewpageractivitydemo;

    import com.example.viewpageractivitydemo.viewpager.TitlePageIndicator;

    import android.os.Bundle;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.view.ViewPager;
    import android.util.Log;

    public class MainViewPager extends FragmentActivity {

        TestFragmentAdapter adapter;
        ViewPager pager;

        @Override
        protected void onCreate(Bundle arg0) {
            // TODO Auto-generated method stub
            super.onCreate(arg0);
            Log.i("MainViewPager","Inside Oncreate");
            setContentView(R.layout.mainviewpager);
            pager = (ViewPager) findViewById(R.id.pager);

            adapter = new TestTitleFragmentAdapter(getSupportFragmentManager());
            pager.setAdapter(adapter);

            TitlePageIndicator indicator = (TitlePageIndicator) findViewById(R.id.indicator);
            indicator.setViewPager(pager);
            pager.setCurrentItem(1);

        }

        @Override
        protected void onResume() {
            // TODO Auto-generated method stub
            super.onResume();

    //      pager.setCurrentItem(1);
        }

    }

Вот код для TestFragmentAdapter.java

package com.example.viewpageractivitydemo;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.util.Log;

public class TestFragmentAdapter extends FragmentPagerAdapter {

    protected static final String[] CONTENT = new String[] { "Filter",
            "Streets", "Around" };
    public String TAG = "TestFragmentAdapter";
    private int mCount = CONTENT.length;

    public TestFragmentAdapter(FragmentManager fm) {
        super(fm);
        // TODO Auto-generated constructor stub
    }

    @Override
    public Fragment getItem(int position) {
        // TODO Auto-generated method stub
        Log.i(TAG, "Inside getItemMethod with position " + position);

        if (position == 0) {
            Log.i("TestFragmentAdapter","Inside if Condition");
            return FilterFragment.newInstance(position);
        } else if (position == 1) {
            return StreetsFragment.newInstance(position);
        } else if (position == 2) {
            return AroundFragment.newInstance(position);
        } else {
            return null;
        }
        // return MainFragment.newInstance(CONTENT[position % CONTENT.length]);

    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return mCount;
    }

    public void setCount(int count) {
        if (count > 0 && count <= 10) {
            mCount = count;
            notifyDataSetChanged();
        }
    }

}

Вот мой код для FilterFragment.java:

package com.example.viewpageractivitydemo;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FilterFragment extends Fragment {

    /*
     * @Override protected Class<? extends Activity> getActivityClass() { //
     * TODO Auto-generated method stub return MyFilterActivity.class; }
     */

    public static Fragment newInstance(int position) {

        Log.i("FilterFragment","Inside New Instasnce");
        FilterFragment filterFragment = new FilterFragment();
        return filterFragment;

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        Log.i("FilterFragment","Inside OcCreateView");
        View view = inflater.inflate(R.layout.filter, null);
        return view;
    }

}

Вот мой код для filter.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#C6CDD4"
    android:gravity="center"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#93A4BA"
            android:gravity="center" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_margin="5dp"
                android:gravity="center"
                android:text="Where Am I"
                android:textColor="#ffffff"
                android:textSize="18dp"
                android:textStyle="bold" >
            </TextView>
        </LinearLayout>

        <com.google.android.maps.MapView
            android:id="@+id/whereami_mapview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:apiKey="0-PaH6rk7RKrZSMd_lqdrZi6FazYyIlX5r6YFyA"
            android:clickable="true" />

        <!--
             <com.google.android.maps.MapView
            android:id="@+id/whereami_mapview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:apiKey="0-PaH6rk7RKrZSMd_lqdrZi6FazYyIlX5r6YFyA" />



        -->
    </LinearLayout>

</LinearLayout>

Пожалуйста, кто-нибудь может предложить мне ответ, чтобы решить мою проблему. Я потратил много часов на это. Все еще не получаю никакого представления о моем вопросе. Спасибо заранее.


person Bhavesh Patadiya    schedule 13.10.2012    source источник


Ответы (2)


Вы можете использовать LocalActivityManager для размещения Activity внутри фрагмента. Это устаревший класс, но он предлагает самое простое решение.

Вот код фрагмента (MyFilterFragment в вашем коде). YourMapActivity — это базовая активность, расширяющая MapActivity.

public class MapFragment extends Fragment {
    private static final String KEY_STATE_BUNDLE = "localActivityManagerState";

    private LocalActivityManager mLocalActivityManager;

    protected LocalActivityManager getLocalActivityManager() {
        return mLocalActivityManager;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Bundle state = null;
        if (savedInstanceState != null) {
            state = savedInstanceState.getBundle(KEY_STATE_BUNDLE);
        }

        mLocalActivityManager = new LocalActivityManager(getActivity(), true);
        mLocalActivityManager.dispatchCreate(state);
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
            //This is where you specify you activity class
        Intent i = new Intent(getActivity(), YourMapActivity.class); 
        Window w = mLocalActivityManager.startActivity("tag", i); 
        View currentView=w.getDecorView(); 
        currentView.setVisibility(View.VISIBLE); 
        currentView.setFocusableInTouchMode(true); 
        ((ViewGroup) currentView).setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
        return currentView;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBundle(KEY_STATE_BUNDLE,
                mLocalActivityManager.saveInstanceState());
    }

    @Override
    public void onResume() {
        super.onResume();
        mLocalActivityManager.dispatchResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mLocalActivityManager.dispatchPause(getActivity().isFinishing());
    }

    @Override
    public void onStop() {
        super.onStop();
        mLocalActivityManager.dispatchStop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mLocalActivityManager.dispatchDestroy(getActivity().isFinishing());
    }
}

Изменить. Поскольку этот ответ был опубликован, Google выпустил Google Maps Android API с поддержкой фрагментов с официальным классом MapFragment.

person LukaCiko    schedule 13.10.2012
comment
я использовал ваш код, но не знал во время работы приложения, я столкнулся с проблемой ClassDefNotFound. Незнал почему. я объявил это в файле Menifest. - person Bhavesh Patadiya; 13.10.2012
comment
Это решает мою проблему очень легко. Спасибо за вашу поддержку. Спасибо большое еще раз!!!! - person Bhavesh Patadiya; 13.10.2012
comment
Он вылетает, когда я прокручиваю страницу просмотра. Ошибка: у указанного потомка уже есть родитель. вы должны сначала вызвать removeview() для дочернего родителя. - person Chirag Shah; 15.10.2012

Чтобы использовать Карты Google, необходимо расширить MapActivity, чего вы не сделали. Ознакомьтесь с этим примером в документации. В духе ремонтопригодности я бы не стал прибегать к решениям, использующим устаревшие функции.

Более надежное решение — расширить MapActivity и скопировать отсутствующую реализацию из FragmentActivity. Если вы не хотите или не нуждаетесь в обратной совместимости со старыми версиями Android, просто используйте MapActivity, а не FragmentActivity, который уже должен включать функции, необходимые для отображения Fragment в Android 3.0 и более поздних версиях.


Изменить: вот проект, который сделал это за вас.

person Reinier    schedule 13.10.2012