android - 另一个 fragment 内的谷歌地图 fragment

标签 android google-maps android-fragments

我有一个抽屉导航,它用 supportmapfragment 替换了框架布局。我第一次能够很好地加载 fragment ,但是再次按下那个抽屉项目会出现可怕的“重复二进制”错误。

我从 Binary XML file line #9: Error inflating class fragment with Google Map Fragment 上读到错误是由于如果 map fragment 存在于 xml 中,则无法从抽屉导航的 fragment 中删除 map fragment 。他建议采用编程方法,所以我尝试了这个:

NavDrawerFirstFragment:

@Override
public void onCreate(Bundle savedInstanceState) {
    Log.d("DEBUG", "In NavDrawerFirstFragment onCreate()");
    super.onCreate(savedInstanceState);
}


public NavDrawerFirstFragment() {
    // fragment needs a no arg ctor
}


public static NavDrawerFirstFragment newInstance(Location currentLoc) {
    NavDrawerFirstFragment firstFragment = new NavDrawerFirstFragment();
    // how to set arguments for this fragment when this method is static
    Bundle args = new Bundle();
    args.putParcelable("current_loc", currentLoc);
    firstFragment.setArguments(args);

    return firstFragment;
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    Log.d("DEBUG", "NavDrawerFirstFragment onCreateView()");
    super.onCreateView(inflater, container, savedInstanceState);
    View view = inflater.inflate(R.layout.fragment_nav_drawer_first, container, false);

    if (mMap == null) {
        mMapFragment = new SupportMapFragment();

        FragmentTransaction ft = getChildFragmentManager().beginTransaction();
        ft.replace(R.id.mapContainer, mMapFragment);
        mMap = mMapFragment.getMap();

    }
    /*if(mMap == null) {
        mMapFragment = (SupportMapFragment)getFragmentManager().findFragmentById(R.id.map);
    }*/

    return view;
}


@Override
public void onStart() {
    Log.d("DEBUG", "NavDrawerFirstFragment onStart()");
    super.onStart();

    mMap.getUiSettings().setRotateGesturesEnabled(false);
    // check for google play services here

    MarkerOptions mo = new MarkerOptions();
    Location initialLoc = getArguments().getParcelable("current_loc");
    LatLng latlong = new LatLng(initialLoc.getLatitude(), initialLoc.getLongitude());

    Marker startingMarker = mMap.addMarker(mo.position(latlong).position(latlong).icon(
            BitmapDescriptorFactory.defaultMarker(
                    BitmapDescriptorFactory.HUE_GREEN)));
    startingMarker.setDraggable(true);
    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlong, 12));
}


@Override
public void onActivityCreated(Bundle savedInstanceState) {
    Log.d("DEBUG", "NavDrawerFirstFragment onActivityCreated");
    super.onActivityCreated(savedInstanceState);
    if (mMap == null) {
        mMap = mMapFragment.getMap();
    }
}


@Override
public void onDetach() {
    Log.d("DEBUG", "NavDrawerFirstFragment onDetach()");
    super.onDetach();
}


@Override
public void onResume() {
    Log.d("DEBUG", "NavDrawerFirstFragment onResume()");
    super.onResume();

    FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
    fragmentTransaction.add(R.id.mapContainer, mMapFragment);
    fragmentTransaction.commit();

    if (mMapFragment != null)
        mMap = mMapFragment.getMap();
}

@Override
public void onPause() {
    Log.d("DEBUG", "NavDrawerFirstFragment onPause()");
    super.onPause();

    if (mMapFragment != null) {
        FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
        fragmentTransaction.remove(mMapFragment);
        fragmentTransaction.commit();
    }
}

fragment_nav_drawer_first.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="wrap_content"
   android:orientation="vertical">

<LinearLayout
    android:id="@+id/navBar"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <EditText
        android:id="@+id/et_location"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="@string/hnt_et_location"
        android:layout_weight="1"
        android:inputType="text" />

    <Button
        android:id="@+id/btn_find"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/str_btn_find" />
</LinearLayout>

<FrameLayout
    android:id="@+id/mapContainer"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"></FrameLayout>

</LinearLayout>

这实际上是另一个SO帖子中提出的解决方案:Error opening SupportMapFragment for second time

当我调试它时,我注意到无论我在进入 onStart() 之前等待多长时间,我的 GoogleMap mMap 仍然是空的。这让我发疯,我真的很感激能够始终如一地访问抽屉导航 fragment 的正确解决方案,它不仅是 map ,而且是搜索栏和我拥有的 map 。

最佳答案

出现这个问题是因为 map 已经退出,而您尝试使用相同的 id 再次添加它.. 所以你需要在 onPause 中删除 map framegnt,并且必须在 onResume 中再次添加它:

@Override
public void onResume() {
    super.onResume();

    FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
    fragmentTransaction.add(R.id.mapContainer, mMapFragment);
    fragmentTransaction.commit();

    if (mMapFragment != null)
        mMap= mMapFragment.getMap();
}

@Override
public void onPause() {
    super.onPause();

    if (mMapFragment != null) {
        FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
        fragmentTransaction.remove(mMapFragment);
        fragmentTransaction.commit();
    }
}

更新:

将您的 onStart 代码移动到 onActivityCreated,如下所示:

mMapFragment = new SupportMapFragment() {



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

            }
        };


    public void initMap()
    {
              if (mMap== null) {
                    mMap= mMapFragment.getMap();
            }
        mMap.getUiSettings().setRotateGesturesEnabled(false);
        // check for google play services here

        MarkerOptions mo = new MarkerOptions();
        Location initialLoc = getArguments().getParcelable("current_loc");
        LatLng latlong = new LatLng(initialLoc.getLatitude(), initialLoc.getLongitude());

        Marker startingMarker = mMap.addMarker(mo.position(latlong).position(latlong).icon(
                BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_GREEN)));
        startingMarker.setDraggable(true);
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlong, 12));
    }

关于android - 另一个 fragment 内的谷歌地图 fragment ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25540266/

相关文章:

android - 如何离线为Android项目添加依赖?

android - 使用倒计时设置按钮启用

google-maps - Google map 服务从v2升级到v3时如何使用PL/SQL生成数字签名?

android - ViewPager,与多个选项卡的 RecyclerView 相同的 fragment

android - 膨胀类 android.support.design.bottomappbar.BottomAppBar 时出错

android - 检查浏览器是否打开(uiautomator/espresso 测试)

javascript - 如何平滑放大谷歌地图中的标记?

android - 如何高效地在谷歌地图中绘制多条折线?

android - 什么时候提交 FragmentTransaction 是安全的?

android - fragment View 通过主视图的 id 查找 View