Fragment Nesting Problem in ILJMALL project: IllegalArgumentException: Binary XML file line #23: Duplicate id,
- Scenario: When you click "category" and return to the "Homepage", an error occurs and the system exits.
- BUG Description: Caused by: java. lang. illegalArgumentException: Binary XML file line #23: Duplicate id 0x7f0d0054, tag null, or parent id 0 xffffffff with another fragment for com. example. sxq123.iljmall. fragmentCatagorySpace
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text = "@string/home"/><fragment android:id = "@+id/fragment_space" android:name = "com.example.sxq123.iljmall.FragmentCatagorySpace" android:layout_width="match_parent" android:layout_height="wrap_content"/></LinearLayout></ScrollView></LinearLayout>
public class FragmentHome extends Fragment { private View view; FragmentCatagorySpace fragmentCatagorySpace ; @Override public View onCreateView(LayoutInflater inflater , ViewGroup container , Bundle savedInsataceState){ view = inflater.inflate(R.layout.fragment_home, null); Log.d(this.getClass().getName()," onCreateView() Begin"); initChildFragment(); return view; } private void initChildFragment(){ Log.d("-------------------","init space "); fragmentCatagorySpace = (FragmentCatagorySpace)getChildFragmentManager().findFragmentById(R.id.fragment_space); if(fragmentCatagorySpace != null){ Log.d("----------------","init space success and no null"); } }}
When project replacement between different framents in the http://www.tuicool.com/articles/FNVN3i activity, FragmentManager will only remove and add the frament, but the frament loaded by themselves in the frament (here is our FragmentCatagorySpace) is not removed. obviously, this is a defect! Because the next frament (FragmentCatagorySpace) is obviously dependent on its parent frament and should be recursively removed at the same time. How can this problem be solved! It is obvious that the frament loaded in the frament (FragmentHome) is removed when this frament (FragmentHome) is not used! This operation can solve the problem by removing it before the re-onCreateView () inflate layout of Fragment! For example, place the remove transaction in onDestroyView () of the parent Fragment for execution.
Public class FragmentHome extends Fragment {private View view; FragmentCatagorySpace fragmentCatagorySpace; @ Override public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle identifier) {view = inflater. inflate (R. layout. fragment_home, null); Log. d (this. getClass (). getName (), "onCreateView () Begin"); initChildFragment (); return view ;}@ Overridepublic void onDestroyVi Ew () {super. onDestroyView (); if (fragmentCatagorySpace! = Null) {Log. d ("-------------------", "space no null"); FragmentManager fragmentManager = getFragmentManager (); if (fragmentManager! = Null &&! FragmentManager. isDestroyed () {final FragmentTransaction fragmentTransaction = fragmentManager. beginTransaction (); if (fragmentTransaction! = Null) {fragmentTransaction. remove (fragmentCatagorySpace ). commit (); // both commit () and commitAllowingStateLoss () are sent to the master thread task queue first. When the master thread is ready, it is executed asynchronously. //// If the transaction of remove child fragmetn is not executed before inflate, a duplicate id exception will occur !!! // FragmentTransaction. commit (); // It can be placed in onCreateView to execute commit (), but occasionally the conflict fragmentTransaction cannot be executed after onSaveInstanceState () occurs. commitAllowingStateLoss (); // immediately execute transaction in the task queue, which is not asynchronous !!!!!!!!!!!!!!! Key points !!!!!!!!!!!!!!!!!!!! // Prevent the remove transaction from being added to the master thread task queue. In this case, the events may not be completed until the parent Fragment re-executes onCreateView, duplicate id exception will also occur // If the removed food is executed in onSaveInstanceState () of the parent Fragment, because onSaveInstanceState () the call does not // every Fragment lifecycle will be called (????), Therefore, the duplicate id exception fragmentManager.exe cutePendingTransactions (); Log. d ("------------------", "space destroy") ;}}} private void initChildFragment () {Log. d ("-------------------", "init space"); fragmentCatagorySpace = (FragmentCatagorySpace) getChildFragmentManager (). findFragmentById (R. id. fragment_space); if (fragmentCatagorySpace! = Null) {Log. d ("----------------", "init space success and no null ");}}}