如何在导航抽屉活动片段中正确使用谷歌地图片段

时间:2016-05-23 06:15:57

标签: android google-maps android-fragments

我试图将google地图片段放在我的应用中,但是当我尝试在Locations类中对视图进行充气时,我一直收到此错误:

android.view.InflateException: Binary XML file line #37: Binary XML file line #37: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #37: Error inflating class fragment
Caused by: android.app.Fragment$InstantiationException: Trying to instantiate a class com.google.android.gms.maps.SupportMapFragment that is not a Fragment
I want to put the maps fragment in another fragment with is loaded in the main activity with the navigation drawer.
Here is my code loading the locations fragment the map should go into:
@Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

        Fragment fragment = new Race();
        toolbar.setTitle(R.string.nav_name_race);
        FragmentManager fragmentManager = getFragmentManager();

        if (id == R.id.nav_race) {
            toolbar.setTitle(R.string.nav_name_race);
            fragment = new Race();
        } else if (id == R.id.nav_pilot) {
            toolbar.setTitle(R.string.nav_name_pilot);
            fragment = new Pilot();
        } else if (id == R.id.nav_locations) {
            toolbar.setTitle(R.string.nav_name_locations);
            fragment = new Locations();
        } else if (id == R.id.nav_channelpicker) {
            toolbar.setTitle(R.string.nav_name_channelpicker);
            fragment = new Channelpicker();
        } else if (id == R.id.nav_band_overview) {
            toolbar.setTitle(R.string.nav_name_band_overview);
            fragment = new BandOverview();
        }

        fragmentManager.beginTransaction()
                .replace(R.id.mainframelayout, fragment)
                .commit();


        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

Locations类:

public class Locations extends Fragment implements OnMapReadyCallback {

    private View view;
    private GoogleMap map;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        this.view = inflater.inflate(R.layout.content_locations, container, false);
        SupportMapFragment mapFragment = (SupportMapFragment) (((FragmentActivity) getActivity()).getSupportFragmentManager().findFragmentById(R.id.map));
        mapFragment.getMapAsync(this);


        //set fab onClickListener
        FloatingActionButton fabtop = (FloatingActionButton) view.findViewById(R.id.fabtop);
        assert fabtop != null;
        fabtop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(view.getContext(), "top", Toast.LENGTH_SHORT).show();
            }
        });

        FloatingActionButton fabbottom = (FloatingActionButton) view.findViewById(R.id.fabbottom);
        assert fabbottom != null;
        fabbottom.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(view.getContext(), "bottom", Toast.LENGTH_SHORT).show();
            }
        });

        return this.view;
    }

    @Override
    public void onMapReady(GoogleMap googleMap)
    {
        map = googleMap;

        // Add a marker in Sydney and move the camera
        LatLng sydney = new LatLng(-34, 151);
        map.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        map.moveCamera(CameraUpdateFactory.newLatLng(sydney));
    }
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="?android:attr/actionBarSize"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity">

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fabtop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right|bottom"
        android:src="@drawable/ic_menu_mylocation"
        app:backgroundTint="#FFFFFF"
        android:layout_above="@+id/fabbottom"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_marginRight="@dimen/fab_margin" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fabbottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right|bottom"
        android:src="@mipmap/ic_add_white_48dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_margin="@dimen/fab_margin" />

    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/map"
        tools:context=".MapsActivity"
        android:name="com.google.android.gms.maps.SupportMapFragment" />

</RelativeLayout>

我认为问题是在片段中有一个片段,因为如果我为地图创建一个新的Activity,一切正常。我仍然是处理片段的初学者,并且不知道在我的应用中插入地图片段的正确方法。

每个tipp都受到赞赏。

1 个答案:

答案 0 :(得分:0)

您不需要像(SupportMapFragment) (((FragmentActivity) getActivity()).getSupportFragmentManager()getFragmentManager()那样在片段中调用Fragment。但是在使用嵌套片段时,您应该使用getChildFragmentManager()而不是getFragmentManager()(请参阅documentation)。

回答您的问题,您只需将代码更新为:

SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
if (mapFragment != null) {
    mapFragment.getMapAsync(this);
}

如果您遇到类似重复ID,标记为null或父ID以及另一个com.google.android.gms.maps.MapFragment 片段的问题。您可以尝试使用here讨论的任何解决方案。或者尝试这个:

private View mContentView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    if (mContentView == null) {
        mContentView = inflater.inflate(R.layout.content_locations, container, false);
    }
    return mContentView;
}

每次都不会使布局膨胀,因此您不会面临复制ID,标记为null或父ID与com.google.android.gms.maps.MapFragment问题的其他片段。 但请确保在attachToRoot(inflater.inflate的最后一个参数)中传递false,否则您可能会遇到类似的异常。指定的子节点已经有父节点。