Android Fragments - 2 Fragment & 1 Frame Layout

2019-02-15 20:07发布

问题:

I am trying to create a layout with three vertical panel - 2 fragments and 1 frame layout. 1st fragment will be a list on selection, 2nd fragment will have different content. on selecting a list item from 2nd fragment, 3rd pane will show the details.

Here's my layout files:

activity_three_pane.xml:

<LinearLayout 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:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:divider="?android:attr/dividerHorizontal"
android:orientation="horizontal"
android:showDividers="middle"
tools:context=".ActivitySectionList" >

<fragment
    android:id="@+id/frg_section_list"
    android:name="eam.droid.pt.entholkaappiyam.FragmentSectionList"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    tools:layout="@android:layout/list_content" />

<fragment
    android:id="@+id/frg_chapter_list"
    android:name="eam.droid.pt.entholkaappiyam.FragmentChapterList"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    tools:layout="@android:layout/list_content" />

<FrameLayout
    android:id="@+id/fl_chapter_detail"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="2" />

</LinearLayout>

activity_section_list.xml:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/frg_section_list"
    android:name="eam.droid.pt.entholkaappiyam.FragmentSectionList"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    tools:context=".ActivitySectionList"
    tools:layout="@android:layout/list_content" />

activity_chapter_list.xml:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/frg_chapter_list"
    android:name="eam.droid.pt.entholkaappiyam.FragmentChapterList"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    tools:context=".ActivityChapterList"
    tools:layout="@android:layout/list_content" />

activity_chapter_detail.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fl_chapter_detail"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ActivityChapterDetail"
    tools:ignore="MergeRootFrame" />

The Java code goes like this:

ActivitySectionList.java

public class ActivitySectionList extends FragmentActivity implements FragmentSectionList.Callbacks

FragmentSectionList.java

public class FragmentSectionList extends ListFragment

ActivityChapterList.java

public class ActivityChapterList extends FragmentActivity implements FragmentChapterList.Callbacks

FragmentChapterList.java

public class FragmentChapterList extends ListFragment

ActivityChapterDetail.java

public class ActivityChapterDetail extends FragmentActivity

FragmentChapterDetail.java

public class FragmentChapterDetail extends Fragment

But the application crashes with Inflate Exception and IllegalStateException. I am trying for the past two day but cant find out where the problem is. If anyone has idea on it, please reply.

Onething I noticed is that it works fine on Phone which takes individual fragment for whole screen. But crashes on Tablet which tries to fit three fragments on the screen. When I debugged, I came to know that FragmentChapterList.java's OnAttach gets called before ActivityChapterList.java's onCreate. That's why, it gives the IllegaltStateException: Activity must implement fragment's callback. so, I tried to implement both the fragments callbacks within ActivitySectionList.java.

like this:

public class ActivitySectionList extends FragmentActivity implements FragmentSectionList.Callbacks, FragmentChapterList.Callbacks

Then it works fine on Tablet. But, not able to retrieve Chapter List on Phone.

Here's my logcat:


02-12 14:14:55.858: E/AndroidRuntime(989): FATAL EXCEPTION: main
02-12 14:14:55.858: E/AndroidRuntime(989): java.lang.RuntimeException: Unable to start activity ComponentInfo{eam.droid.pt.entholkaappiyam/eam.droid.pt.entholkaappiyam.ActivitySectionList}: android.view.InflateException: Binary XML file line #20: Error inflating class fragment
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.app.ActivityThread.access$600(ActivityThread.java:130)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.os.Handler.dispatchMessage(Handler.java:99)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.os.Looper.loop(Looper.java:137)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.app.ActivityThread.main(ActivityThread.java:4745)
02-12 14:14:55.858: E/AndroidRuntime(989):  at java.lang.reflect.Method.invokeNative(Native Method)
02-12 14:14:55.858: E/AndroidRuntime(989):  at java.lang.reflect.Method.invoke(Method.java:511)
02-12 14:14:55.858: E/AndroidRuntime(989):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
02-12 14:14:55.858: E/AndroidRuntime(989):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
02-12 14:14:55.858: E/AndroidRuntime(989):  at dalvik.system.NativeStart.main(Native Method)
02-12 14:14:55.858: E/AndroidRuntime(989): Caused by: android.view.InflateException: Binary XML file line #20: Error inflating class fragment
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
02-12 14:14:55.858: E/AndroidRuntime(989):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:256)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.app.Activity.setContentView(Activity.java:1867)
02-12 14:14:55.858: E/AndroidRuntime(989):  at eam.droid.pt.entholkaappiyam.ActivitySectionList.onCreate(ActivitySectionList.java:20)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.app.Activity.performCreate(Activity.java:5008)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
02-12 14:14:55.858: E/AndroidRuntime(989):  ... 11 more
02-12 14:14:55.858: E/AndroidRuntime(989): Caused by: java.lang.IllegalStateException: Activity must implement fragment's callbacks.
02-12 14:14:55.858: E/AndroidRuntime(989):  at eam.droid.pt.entholkaappiyam.FragmentChapterList.onAttach(FragmentChapterList.java:84)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:867)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1066)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1168)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:280)
02-12 14:14:55.858: E/AndroidRuntime(989):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676)

Can anyone please tell me where I mightbe going wrong? If anyone comes across tutorial or example of 3 vertical panel(2 list and 1 detail), please point me to it.

Here's the detailed scenario:

回答1:

I'm assuming that activity_three_pane.xml only gets inflated for tablets, and in the ActivitySectionList class. In this case, for tablets, both fragments FragmentSectionList and FragmentChapterList are inflated as part of your layout, thus you need to implement callbacks for both in ActivitySectionList, which is the source of your exception.

This setup seems very convoluted and confusing. I would recommend splitting your activities so you're not overlapping code. This will help you diagnose problems much easier, and clean up your code. Example:

public class BookActivity extends FragmentActivity implements FragmentSectionList.Callbacks, FragmentChapterList.Callbacks
{

    public void onCreate(Bundle savedInstanceState) {

        setContentView(R.layout.activity_three_pane);
    }
}

public class ActivitySectionList extends FragmentActivity implements FragmentSectionList.Callbacks
{

    public void onCreate(Bundle savedInstanceState) {

        setContentView(R.layout.activity_section_list);
    }
}

Then in whichever activity that calls these activites:

if( ( getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK ) == Configuration.SCREENLAYOUT_SIZE_XLARGE ) {
    startActivity( new Intent(this, BookActivity.class);
}
else {
    startActivity( new Intent(this, ActivitySectionList.class);
}


回答2:

Is your activity extending FragmentActivity?.. if not try extending FragmentActivity instead of just Activity.



回答3:

A wild guess: Can it be that FragmentActivity (support library) is using Fragment (non-support library)? If that is the case: Ensure that you stick to support library (check imports) or use Android 3+.



回答4:

It sounds like FragmentChapterList is extending android.app.ListFragment instead of the proper android.support.v4.app.ListFragment. I would check your imports in FragmentChapterList to make sure that the ListFragment import is actually the support library version.