2

当我的应用程序在单列模式下运行时,点击ListFragment A中的项目会使用对主 Activity 的回调以编程方式启动Fragment B以显示其他信息。我以这种方式启动Fragment B :

// Create the new fragment and set an argument pointing to the entry's ID in the database
FragmentEntryDetails newFragment = new FragmentEntryDetails();
Bundle args = new Bundle();
args.putInt("entryID", entryID);
newFragment.setArguments(args);

// Specify where in the view we want to place the fragment, then add it to the backstack so the user can
// return to the previous fragment
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();

当我点击 Back 按钮返回ListFragment A中的搜索结果列表时,应用程序崩溃并出现以下 IllegalStateException:

03-06 09:21:53.273: E/AndroidRuntime(32760): FATAL EXCEPTION: main
03-06 09:21:53.273: E/AndroidRuntime(32760): java.lang.IllegalStateException: Content view not yet created
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.app.ListFragment.ensureList(ListFragment.java:386)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.app.ListFragment.getListView(ListFragment.java:280)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at com.test.dictApp.FragmentSearch.onActivityCreated(FragmentSearch.java:98)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.app.Fragment.performActivityCreated(Fragment.java:1703)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:903)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.app.BackStackRecord.popFromBackStack(BackStackRecord.java:764)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1484)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:490)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.app.Activity.onBackPressed(Activity.java:2167)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.app.Activity.onKeyUp(Activity.java:2145)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.view.KeyEvent.dispatch(KeyEvent.java:2633)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.app.Activity.dispatchKeyEvent(Activity.java:2375)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1847)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.view.ViewRootImpl.deliverKeyEventPostIme(ViewRootImpl.java:3701)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.view.ViewRootImpl.handleImeFinishedEvent(ViewRootImpl.java:3651)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:2818)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.os.Handler.dispatchMessage(Handler.java:99)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.os.Looper.loop(Looper.java:137)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at android.app.ActivityThread.main(ActivityThread.java:5041)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at java.lang.reflect.Method.invokeNative(Native Method)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at java.lang.reflect.Method.invoke(Method.java:511)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
03-06 09:21:53.273: E/AndroidRuntime(32760):    at dalvik.system.NativeStart.main(Native Method)

错误指向ListFragment A的 onActivityCreated() 函数中的 setAdapter() :

@Override
public void onActivityCreated(Bundle savedInstanceState)
{
    // Tell the main activity that this fragment has menu elements to declare
    super.onActivityCreated(savedInstanceState);
    setHasOptionsMenu(true);

    adapter = new FragmentSearchCursorAdapter(getActivity(), null, 0);
    // Assign our CursorAdapter
    getListView().setAdapter(adapter);

    Bundle args = getSQLArgs("dictionary");
    // Load up the cursor that will handle the SQL grunt work
    getLoaderManager().initLoader(SEARCH_LOADER_ID, args, this);
}

Why is getListView().setAdapter() causing a problem? According to the Fragment lifecycle, the listView should be available for manipulation. Should I only be setting the adapter if it hasn't already been set?

Edit: I figured it out, see my Answer below.

4

1 回答 1

4

I just recently earned enough credit to answer my own questions, so I've decided to turn my comments into an actual Answer.

The solution was to move the assignment of my FragmentSearchCursorAdapter to ListFragment A's onCreateView() method, and then use setListAdapter() instead of getListView().setAdapter(), as below:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    // Specify the fragment layout file for this fragment class
    View view = inflater.inflate(R.layout.fragment_search, container, false);
    // Assign our CursorAdapter
    adapter = new FragmentSearchCursorAdapter(getActivity(), null, 0);
    setListAdapter(adapter);

    return view;
}
于 2013-07-25T21:14:16.260 回答