I\'m trying make an app that I\'m building take a search term from the main activity, return results, and then have the results be clickable such that a detail could be view
This line
03-21 22:32:03.297: E/AndroidRuntime(764): Caused by: java.lang.IllegalArgumentException: Binary XML file line #7: Duplicate id 0x7f070003, tag null, or parent id 0x0 with another fragment for com.example.blobtag2.ListFragmentClickable
specifically the part at the end
Duplicate id 0x7f070003, tag null, or parent id 0x0 with another fragment for com.example.blobtag2.ListFragmentClickable
is telling you that at some point in the lifetime of your activity you're trying to create a view for ListFragmentClickable when one already exists. You need to figure out how this is occurring.
The problem is the fragment on xml is loaded twice, and the second time it is added to the FragmentManager you get a IllegalArgumentException. I got the same problem yesterday.
My solution, I change it to re-create the fragment dynamically instead of define it on the xml file:
Change this xml file part:
<fragment
android:id="@+id/fragment_content"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_marginTop="?android:attr/actionBarSize"
class="com.example.blobtag2.ListFragmentClickable" ></fragment>
To this instead:
<FrameLayout
android:id="@+id/fragment_content"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_marginTop="?android:attr/actionBarSize" />
An then in the onCreate, yo should replace FrameLayout for a new fragment:
Fragment fragment = new ListFragmentClickable();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment_content, fragment);
ft.commit();
And then you have the same but, you won't get a Duplicate ID error.
I had the same problem with fragment called twice and on the second time it crashed. Solution is to implement the remove statement in onDetach method:
@override
public void onDetach(){
super.onDetach();
FragmentManager fm = getFragmentManager()
Fragment xmlFragment = fm.findFragmentById(R.id.yourfragmentid);
if(xmlFragment != null){
fm.beginTransaction().remove(xmlFragment).commit();
}
}
It occurs when fragments are defined in XML (statically): FragmentManager doesn't manage child fragments if parent fragment is destroyed. Then, it breaks ("duplicate id" error) when the XML is inflated for the second time.
I bypass this problem removing the XML fragment manually when parent is destroyed, with this code in the parent fragment:
@Override
public void onDestroyView() {
FragmentManager fm = getFragmentManager();
Fragment xmlFragment = fm.findFragmentById(R.id.XML_FRAGMENT_ID);
if (xmlFragment != null) {
fm.beginTransaction().remove(xmlFragment).commit();
}
super.onDestroyView();
}
Note for copypasters: XML_FRAGMENT_ID is the id of the fragment in the XML ;)
Furthermore, I prefer a new class that wraps XML fragments. It simplyfies the code since you just need to extend your fragment class from it. Add this class to your project:
package net.treboada.mytests.fragments;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.util.AttributeSet;
public class XmlFragment extends Fragment {
@Override
public void onInflate(Activity activity, AttributeSet attrs,
Bundle savedInstanceState) {
FragmentManager fm = getFragmentManager();
if (fm != null) {
fm.beginTransaction().remove(this).commit();
}
super.onInflate(activity, attrs, savedInstanceState);
}
}
Then, extend your XML fragment classes:
package net.treboada.mytests.fragments;
public class TestXmlFragment01 extends XmlFragment {
// ...
}
and voilà! :)
You can extend you fragment (which you load in xml) from XmlFragment. It handles parent FragmentManager and removes itself.
public class XmlFragment extends BaseFragment {
@Override
public void onDestroyView() {
Fragment parentFragment = getParentFragment();
FragmentManager manager;
if (parentFragment != null) {
// If parent is another fragment, then this fragment is nested
manager = parentFragment.getChildFragmentManager();
} else {
// This fragment is placed into activity
manager = getActivity().getSupportFragmentManager();
}
manager.beginTransaction().remove(this).commitAllowingStateLoss();
super.onDestroyView();
}
}
If you were reading the other answers here feeling that they seemed correct, look here https://stackoverflow.com/a/19815266/1139784 because it references the documentation explaining how this is not supported (at least in my case, it is hard to tell from this question whether the layout fragment nesting is happening)
Note: You cannot inflate a layout into a fragment when that layout includes a <fragment>.
Nested fragments are only supported when added to a fragment dynamically.
More data here Best practice for nested fragments in Android 4.0, 4.1 (<4.2) without using the support library
Edit: Also, if you're considering using nested fragments and don't need the lifecycle management, you can create a custom view group (like extending LinearLayout) instead. http://www.vogella.com/tutorials/AndroidCustomViews/article.html