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:

  1. why have 1 instance of categoryfragment after adding multiple times , how fix this?

  2. 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

  1. i cannot use android:name=...categoryactivity.categoryfragment instead of android:name=...categoryactivity$categoryfragment still have same error
  2. 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

  1. change class attribute in fragment tag in xml android:name , add qualified fragment class name i.e. android:name = "mypackage.categoryfragment"

  2. 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

Popular posts from this blog

sql - VB.NET Operand type clash: date is incompatible with int error -

SVG stroke-linecap doesn't work for circles in Firefox? -

python - TypeError: Scalar value for argument 'color' is not numeric in openCV -