【问题标题】:SupportMapFragment on DialogFragment error on show()SupportMapFragment on DialogFragment on show() 错误
【发布时间】:2014-08-17 12:16:12
【问题描述】:

我正在尝试显示一个内部带有 SupportMapFragment 的 DialogFragment。

当我将片段作为常规片段加载时 - 它工作得很好。

当我使用show() 函数将片段作为对话框加载时,我收到以下堆栈跟踪错误:

03-14 16:54:20.443: E/AndroidRuntime(20856): FATAL EXCEPTION: main
03-14 16:54:20.443: E/AndroidRuntime(20856): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.coapps.pico/com.coapps.pico.MainActivity}: android.view.InflateException: Binary XML file line #47: Error inflating class fragment
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2110)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2135)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.ActivityThread.access$700(ActivityThread.java:140)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1237)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.os.Handler.dispatchMessage(Handler.java:99)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.os.Looper.loop(Looper.java:137)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.ActivityThread.main(ActivityThread.java:4921)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at java.lang.reflect.Method.invokeNative(Native Method)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at java.lang.reflect.Method.invoke(Method.java:511)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at dalvik.system.NativeStart.main(Native Method)
03-14 16:54:20.443: E/AndroidRuntime(20856): Caused by: android.view.InflateException: Binary XML file line #47: Error inflating class fragment
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at com.coapps.pico.fragments.BasicFragment.onCreateDialog(BasicFragment.java:53)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:295)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1082)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:310)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at com.coapps.pico.fragments.BasicFragment.onCreateDialog(BasicFragment.java:53)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:295)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:570)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at com.coapps.pico.MainActivity.onStart(MainActivity.java:86)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1178)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.Activity.performStart(Activity.java:5216)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2083)
03-14 16:54:20.443: E/AndroidRuntime(20856):    ... 11 more
03-14 16:54:20.443: E/AndroidRuntime(20856): Caused by: java.lang.IllegalArgumentException: Binary XML file line #47: Duplicate id 0x7f05008c, tag null, or parent id 0x0 with another fragment for com.google.android.gms.maps.SupportMapFragment
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:296)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676)
03-14 16:54:20.443: E/AndroidRuntime(20856):    ... 36 more

这是我的片段布局:

<?xml version="1.0" encoding="utf-8"?>
<!-- dialog layout -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="20dp"
    android:background="@drawable/background_white"
    android:orientation="vertical"
    android:paddingBottom="15dp"
    android:paddingTop="15dp"
    android:paddingLeft="20dp"
    android:paddingRight="20dp" >

    <!-- dialog caption -->

    <TextView
        android:id="@+id/fragment_create_public_event_caption_textview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="left"
        android:hint="@string/hint_event_name"
        android:text="@string/create_quick_event"
        android:textColor="@color/text_grey"
        android:textSize="12sp" />

    <!-- event name -->

    <EditText
        android:id="@+id/fragment_create_public_event_event_name_edittext"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:background="@drawable/edittext_background"
        android:drawableLeft="@drawable/icon_name"
        android:drawablePadding="10dp"
        android:hint="@string/hint_event_name"
        android:paddingBottom="5dp"
        android:paddingLeft="10dp"
        android:paddingTop="5dp"
        android:textAppearance="@android:style/TextAppearance.Small"
        android:textColorHint="@color/text_grey" />

    <!-- map -->

    <fragment
        android:id="@+id/fragment_create_public_event_map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="fill_parent"
        android:layout_height="100dp"
        android:layout_marginTop="5dp" />

    <!-- create button -->

    <TextView
        android:id="@+id/fragment_create_public_event_create_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="@drawable/button_orange"
        android:clickable="true"
        android:drawableLeft="@drawable/button_create_quick_event"
        android:drawablePadding="5dp"
        android:layout_gravity="center_horizontal"
        android:gravity="center"
        android:paddingBottom="5dp"
        android:paddingLeft="20dp"
        android:paddingRight="20dp"
        android:paddingTop="5dp"
        android:text="@string/create_quick_event_button"
        android:textAppearance="@android:style/TextAppearance.Large"
        android:textColor="@android:color/white" />

</LinearLayout>

这是我的 MapFragment:

public class CreatePublicEventFragment extends BasicFragment{

    /**
     * Tag for creating the public event
     */
    public static final String CREATE_PUBLIC_EVENT_TAG = "createPublicEvent";

    /**
     * create a new instance of {@link CreatePublicEventFragment}
     */
    public static CreatePublicEventFragment newInstance()
    {
        Bundle args = new Bundle();
        CreatePublicEventFragment fragment = new CreatePublicEventFragment();       
        //put the type as dialog
        args.putInt(BasicFragment.KEY_TYPE, BasicFragment.DIALOG);
        fragment.setArguments(args);
        return fragment;        
    }   

    /**
     * The event's name {@link EditText}
     */
    private EditText name;

    /**
     * The create button {@link TextView}
     */
    private TextView createButton;

    /**
     * The google's map {@link GoogleMap}
     */
    private GoogleMap map;

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_create_public_event;
    }

    @Override
    protected void findViews(View view) {
        name = (EditText) view.findViewById(R.id.fragment_create_public_event_event_name_edittext);
        createButton = (TextView) view.findViewById(R.id.fragment_create_public_event_create_textview);
        //get the map
        SupportMapFragment mapFramgment = ((SupportMapFragment) getMainActivity().getSupportFragmentManager().findFragmentById(R.id.fragment_create_public_event_map));
        map = mapFramgment.getMap();        
    }

    @Override
    protected void setViews() {
        centerTheMap();
    }

    /**
     * Center the map to user's position
     */
    private void centerTheMap()
    {
        LatLng position;
        Marker marker;
        //get the user
        PicoUser user = getMainActivity().getPicoUser();        
        LocationClient locationClient= getMainActivity().getPicoLocationManager().getLocationClient();
        if (locationClient == null || !locationClient.isConnected())
            return;
        //get the last known location
        user.setLocation(getMainActivity().getPicoLocationManager().getLocationClient().getLastLocation());
        //create a LatLng
        position = new LatLng(user.getLocation().getLatitude(), user.getLocation().getLongitude());     
        marker = map.addMarker(new MarkerOptions().position(position).title("You are here").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_map_pin)));
        marker.showInfoWindow();
        map.animateCamera(CameraUpdateFactory.newLatLng(position));     
    }
}

这是我的 FragmentActivity onCreate():

    @Override
    protected void onCreate(Bundle savedInstanceState) {        
        super.onCreate(savedInstanceState);     
        setContentView(R.layout.main_activity);     
        if (!checkPlayServices())
            return;         
        //create application's managers
        createManagers();
        //showFragment(null, new CreatePublicEventFragment(), false, true);
        CreatePublicEventFragment.newInstance().show(getSupportFragmentManager(), CreatePublicEventFragment.CREATE_PUBLIC_EVENT_TAG);
}

【问题讨论】:

    标签: android google-maps


    【解决方案1】:

    根本问题与this SO question中的问题相同,我的回答类似。

    虽然我没有看到您的 ...BasicFragment.onCreateDialog 方法的代码,但我看到您的布局包含 SupportMapFragment 的 &lt;fragment.../&gt; 声明。当您将其放入 DialogFragment 时,您在使用嵌套/子片段时违反了其中一项限制:

    正如 4.2 API changes doc 中隐晦地指出的那样

    当布局包含&lt;fragment&gt;.时,您不能将布局膨胀到片段中
    只有以编程方式添加到片段时才支持嵌套片段。

    在这些条件下尝试上述膨胀将导致您看到的 InflateException(Error inflating class fragment)。

    相反,您的 DialogFragment 的布局应该包含 SupportMapFragment 的 &lt;FrameLayout.../&gt; - 替换显式的 &lt;fragment.../&gt; - 您可以使用它以编程方式添加 SupportMapFragment 并避免异常。


    注意:必须通过 getChildFragmentManager() 中的 FragmentManager 管理子/嵌套片段(支持库中也有一个版本),因此,您可能希望在 CreatePublicEventFragment 类中将现有调用更改为 getSupportFragmentManager()(不是来自 FragmentActivity 的调用用于 .show(...) em>) 在设置 FragmentTransaction 以编程方式添加地图片段时。

    在您的情况下,您需要确保 BasicFragment 超类不会尝试使用错误的 FragmentManager,然后根据需要覆盖任何方法以使用正确的 API 来处理嵌套/子片段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多