【问题标题】:How to properly use the google maps fragment in a navigation drawer activity fragment如何在导航抽屉活动片段中正确使用谷歌地图片段
【发布时间】:2016-05-23 06:15:56
【问题描述】:

我正在尝试将 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

我想将地图片段放在另一个片段中,并使用导航抽屉加载到主活动中。

这是我加载地图应该进入的位置片段的代码:

@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;
    }

位置类:

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,一切正常。我仍然是使用片段的初学者,不知道在我的应用中插入地图片段的正确方法。

感谢每一个提示。

【问题讨论】:

    标签: android google-maps android-fragments


    【解决方案1】:

    您不需要在片段中调用(SupportMapFragment) (((FragmentActivity) getActivity()).getSupportFragmentManager(),因为您在Fragment 中有getFragmentManager()。但是在使用嵌套片段时,您应该使用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;
    }
    

    它不会每次都膨胀布局,因此您不会面对 com.google.android.gms.maps.MapFragment 问题的另一个片段的重复 ID、标签 null 或父 ID。 但请确保您在 attachToRoot(inflater.inflate 的最后一个参数)中传递 false,否则您可能会遇到异常,例如 指定的孩子已经有父母。

    【讨论】:

    • 我尝试了您的解决方案,但无法编译,因为它不允许我将 getChildFragmentManager() 返回的片段转换为 SupportMapFragment
    • @Felix 你能分辨出你的Locations 类是从android.support.v4.app.Fragment 还是android.app.Fragment 扩展而来的?
    • 从android.app.Fragment扩展而来
    • @Felix 然后你必须将它从android.support.v4.app.Fragment 扩展为使用SupportMapFragment 并在你的Activity 中的Adapter 中进行更改,或者如果你更喜欢直接使用android.app.Fragment,那么你必须使用MapFragment 在任何地方都可以代替 SupportMapFragment,就像在您的 xml 中将 com.google.android.gms.maps.SupportMapFragment 更改为 com.google.android.gms.maps.MapFragment 并相应地在您的 Fragment 中一样。你明白了吗?
    • 我将所有片段更改为 android.support.v4.app.Fragment,现在一切正常。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多