Android add fragment multiple times but just one instance found -
my activity contains 1 fragment list of items.
activity class:
public class categoryactivity extends actionbaractivity { @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_subcategory); setupactionbar(); categoryfragment fragment = (categoryfragment) getsupportfragmentmanager().findfragmentbyid(r.id.category_fragment); fragment.setbrand(mbrand); } @override public void ondestroy() { super.ondestroy(); uiutils.unbinddrawables(findviewbyid(r.id.rootview)); categoryfragment fragment = (categoryfragment) getsupportfragmentmanager().findfragmentbyid(r.id.category_fragment); if(fragment != null) getsupportfragmentmanager().begintransaction().remove(fragment).commit(); system.gc(); } public static class categoryfragment extends fragment { private listview mlistview; private categoryadapter madapter; private category mroot; private list<category> mcategories; private brand brand; public categoryfragment(){} public void setbrand(brand brand) { this.brand = brand; } private boolean misanimating; @override public view oncreateview(layoutinflater inflater, @nullable viewgroup container, @nullable bundle savedinstancestate) { view view = inflater.inflate(r.layout.fragment_category, container, false); mlistview = (listview) view.findviewbyid(r.id.list_view); try { if (mcategories == null) { loadcategories(appcontroller.getinstance().getcategory()); } if (mcategories != null) { madapter = new categoryadapter(getactivity(), mroot); madapter.setlistener(new categoryadapter.listener() { @override public void oncategoryclick(string category) { if (brand == null) return; utils.openqueryview(getactivity(), category, brand); } @override public void opensubcategory(category category) { opensubcategoriesview(category); } @override public void onbrowseallclick(category category) { if (brand == null) return; if (category.name.equals(category.root)) { utils.openqueryview(getactivity(), category.name, brand); } else { utils.openstoreactivity(getactivity(), category, brand); } } }); mlistview.setadapter(madapter); } }catch (exception e){ logd(tag, e.getmessage()); return view; } return view; } private void loadcategories(category root) { // stuff here... work } private void opensubcategoriesview(category category) { analyticsmanager.sendscreenview(screen_name); final categoryfragment fragment = new categoryfragment(); fragment.setcategories(category); fragment.setbrand(brand); if (misanimating) { return; } misanimating = true; fragmenttransaction transaction = getfragmentmanager().begintransaction(); transaction.setcustomanimations(r.anim.slide_in_right, 0, 0, r.anim.slide_out_right); transaction.add(r.id.category_fragment, fragment); transaction.addtobackstack(null); transaction.commit(); misanimating = false; list<fragment> fs = getfragmentmanager().getfragments(); for(int = 0; i< fs.size(); i++){ logd(tag, "fragment[" + + "]: " + fs.get(i).getactivity()); } } public void setcategories(category category) { loadcategories(category); } } }
activity layout xml:
<fragment android:id="@+id/the_main_fragment" android:tag="firstfragment" android:name="com.greelane.gapp.ui.categoryactivity$categoryfragment" android:layout_width="match_parent" android:layout_height="match_parent" /> <linearlayout android:background="@drawable/header_shadow" android:layout_width="match_parent" android:layout_height="12dp"></linearlayout> </relativelayout>
everytime click on item, new categoryfragment added fragmentmanager of activity same fragment class in xml layout (category_fragment id) child , if child has children, conception repeated.
i try log see how many fragments have, each time clicked on item:
function opensubcategoriesview
list<fragment> fs = getfragmentmanager().getfragments(); // fs size > 1, 1 instance of categoryfragment for(int = 0; i< fs.size(); i++){ logd(tag, "fragment[" + + "]: " + fs.get(i).getactivity()); }
first time after navigating activity click on item, creates 1 fragment, fs size 1;
then click > click on item, see fs size 2, there 1 instance of categoryfragment found.
i don't know how work fragment in activity, sometime app crashes @ line of oncreateactivity setcontentview(r.layout.activity_subcategory);
error log:
caused by: android.view.inflateexception: binary xml file line #14: error inflating class fragment
the line #14 start in xml layout
fragment android:id="@+id/category_fragment" ...
so question is:
why have 1 instance of categoryfragment after adding multiple times , how fix this?
why sometime inflate exception ad described above , how fix this?
#updated1
error log second question, cannot find exception stack trace:
01-21 11:16:54.276 16783-16783/? w/system.err: java.lang.runtimeexception: unable start activity componentinfo{vn.app.alezaa/com.greelane.gapp.ui.categoryactivity}: android.view.inflateexception: binary xml file line #14: error inflating class fragment 01-21 11:16:54.279 16783-16783/? w/system.err: caused by: android.view.inflateexception: binary xml file line #14: error inflating class fragment 01-21 11:16:54.282 16783-16783/? w/system.err: caused by: android.support.v4.app.fragment$instantiationexception: unable instantiate fragment com.greelane.gapp.ui.categoryactivity$categoryfragment: make sure class name exists, public, , has empty constructor public 01-21 11:16:54.286 16783-16783/? w/system.err: caused by: java.lang.instantiationexception: can't instantiate class com.greelane.gapp.ui.categoryactivity$categoryfragment; no empty constructor
#updated2
- i cannot use
android:name=...categoryactivity.categoryfragment
instead ofandroid:name=...categoryactivity$categoryfragment
still have same error - the empty contructor had @ first time post question.
i have editted code add new categoryfragment like:
final categoryfragment fragment = new categoryfragment(); fragment.setcategories(category); fragment.setbrand(brand); if (misanimating) { return; } misanimating = true; fragmenttransaction transaction = getfragmentmanager().begintransaction(); transaction .setcustomanimations(r.anim.slide_in_right, 0, 0, r.anim.slide_out_right) .replace(r.id.container, fragment, category.title)// set tag title of ctg .addtobackstack(category.title) .commit(); misanimating = false; list<fragment> fs = getfragmentmanager().getfragments(); // `error raised here after 2 times add categoryfragment, **fs** size > 1, 1 instance of it.` for(int = 0; i< fs.size(); i++){ logd(tag, "fragment[" + + "]: " + fs.get(i).getactivity()); }
xml layout edited:
<fragment android:id="@+id/the_main_fragment" android:tag="firstfragment" android:name="com.greelane.gapp.ui.categoryactivity$categoryfragment" android:layout_width="match_parent" android:layout_height="match_parent" /> <linearlayout android:background="@drawable/header_shadow" android:layout_width="match_parent" android:layout_height="12dp"></linearlayout> </relativelayout>
or need seperate categoryfragment other class , turn non-static, cause cannot remove static. ideas?
to answer question loading same fragment multiple times can check here, says in note section
each fragment requires unique identifier system can use restore fragment if activity restarted (and can use capture fragment perform transactions, such remove it). there 3 ways provide id fragment:
- supply android:id attribute unique id.
- supply android:tag attribute unique string.
- if provide neither of previous two, system uses id of container view.
so can use same fragment multiple times need have unique id , tag if added through layout.xml or unique tag if added through code.
in case can consider using unique field category object used tag when loading fragment, every categoryfragment instance load have unique tag , considered unique in fragmentmanager stack.
for second question, 2 suggestions
change class attribute in fragment tag in xml android:name , add qualified fragment class name i.e.
android:name = "mypackage.categoryfragment"
also per crash if check, mentioned java.lang.instantiationexception: can't instantiate class com.greelane.gapp.ui.categoryactivity$categoryfragment; no empty constructor. create 1 empty or default constructor like
public categoryfragment(){
}
Comments
Post a Comment