1

我在活動中有2個片段。第一個片段A有一個recyclerview,其中一行包含viewpager。該ViewPager具有使用FragmentStatePagerAdapter創建的片段數量(每個頁面都是一個片段)。現在點擊一個動作項目,我將用戶導航到片段B.在這裏,我使用FragmentTransaction的replace()方法將片段A替換爲B.現在按後退按鈕上的片段B,應用程序崩潰與以下情況除外:在回來按下,回到具有片段的RecyclerView導致IllegalArgumentException

02-06 18:21:49.038: W/System.err(6916): java.lang.IllegalArgumentException: No view found for id 0x7f110209 (com.example:id/vPager) for fragment VFragment{da512cf #0 id=0x7f110209} 
02-06 18:21:49.038: W/System.err(6916):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:939) 
02-06 18:21:49.038: W/System.err(6916):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126) 
02-06 18:21:49.038: W/System.err(6916):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1108) 
02-06 18:21:49.038: W/System.err(6916):  at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1917) 
02-06 18:21:49.038: W/System.err(6916):  at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1800) 
02-06 18:21:49.038: W/System.err(6916):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:967) 
02-06 18:21:49.038: W/System.err(6916):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126) 
02-06 18:21:49.038: W/System.err(6916):  at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:957) 
02-06 18:21:49.039: W/System.err(6916):  at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1541) 
02-06 18:21:49.039: W/System.err(6916):  at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:502) 
02-06 18:21:49.039: W/System.err(6916):  at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:176) 
02-06 18:21:49.039: W/System.err(6916):  at android.support.v7.app.ActionBarActivity.onBackPressed(ActionBarActivity.java:298) 
02-06 18:21:49.039: W/System.err(6916):  at com.example.MainActivity.onBackPressed(MainActivity.java:2049) 
02-06 18:21:49.039: W/System.err(6916):  at android.app.Activity.onKeyUp(Activity.java:2453) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.KeyEvent.dispatch(KeyEvent.java:2633) 
02-06 18:21:49.039: W/System.err(6916):  at android.app.Activity.dispatchKeyEvent(Activity.java:2704) 
02-06 18:21:49.039: W/System.err(6916):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2221) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:3918) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3880) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3578) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3635) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3476) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3449) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3502) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3468) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3611) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:3772) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2208) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:1849) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1840) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2185) 
02-06 18:21:49.039: W/System.err(6916):  at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141) 
02-06 18:21:49.039: W/System.err(6916):  at android.os.MessageQueue.nativePollOnce(Native Method) 
02-06 18:21:49.039: W/System.err(6916):  at android.os.MessageQueue.next(MessageQueue.java:143) 
02-06 18:21:49.039: W/System.err(6916):  at android.os.Looper.loop(Looper.java:122) 
02-06 18:21:49.040: W/System.err(6916):  at android.app.ActivityThread.main(ActivityThread.java:5221) 
02-06 18:21:49.040: W/System.err(6916):  at java.lang.reflect.Method.invoke(Native Method) 
02-06 18:21:49.040: W/System.err(6916):  at java.lang.reflect.Method.invoke(Method.java:372) 
02-06 18:21:49.040: W/System.err(6916):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 
02-06 18:21:49.040: W/System.err(6916):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 

需要注意的是,如果我使用FragmentTransaction的add()方法添加片段B,再回到按不崩潰的應用程序。從上面的崩潰日誌看來,甚至在recyclerview更新其視圖之前,viewpager子片段正在嘗試查找viewpager。如何防止這種情況或延遲碎片狀態保留過程,直到再循環視圖再次準備好爲止?

回答

3

我遇到了類似的問題(我沒有使用替換,但我使用了添加),並且我找到了一個解決方案。您需要在父代片段(片段A)的onCreateView()或onActivityCreated()中分離嵌套片段。然後,在該片段的綁定調用中,您可以重新連接。以下是一些示例代碼:

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 

    FragmentManager fragmentManager = getChildFragmentManager(); 
    Fragment fragment = fragmentManager.findFragmentById(R.id.nested_fragment); 
    if (fragment != null) { 
     fragmentManager.beginTransaction().detach(fragment).commit(); 
     fragmentManager.executePendingTransactions(); 
    } 
} 

請注意,調用executePendingTransactions()很重要。如果我正確理解問題,這是因爲onActivityCreated()正在作爲FragmentTransaction的一部分進行處理。如果您不調用executePendingTransactions,它將在處理分離呼叫之前繼續嵌套分段。

在您的適配器綁定調用

然後,做這樣的事情:

public void bindNestedFragment(View view) { 
    Fragment fragment = mFragmentManager.findFragmentById(R.id.nested_fragment); 
    if (fragment == null) { 
     // Create/add fragment here 
    } else { 
     mFragmentManager.beginTransaction.attach(fragment).commit(); 
    } 
} 

你必須通過一些手段來給片段經理適配器接入(我只是通過它的構造函數) 。希望這有助於!

+0

感謝您花時間回答。我會檢查一段時間,並回到這個帖子與反饋。 – Ankur 2015-03-10 07:09:20

+0

很好...它的工作.. – Ankur 2015-03-10 10:09:12

+0

很高興聽到它!我花了一段時間才弄清楚這一點,所以我想我會在我做這件事時發佈我的解決方案。 – 2015-03-10 23:03:52