Android restrict fragments only one time go to back stack -
hello guys i'm using bottomnavigationview
each item of navigation view open fragment store in back-stack, if item selected multiple times back-stack store latest instance of fragment. mean when pressing button fragment open 1 time only.
such as, there 3 fragments..a,b,c
fragment pattern: a-b-c-b-a-c-a-c
back press output should be: c-a-b-exit
but pattern- c-a-c-a-b-c-b-a-exit
here code i'm using-
@override public boolean onnavigationitemselected(@nonnull menuitem item) { switch (item.getitemid()){ case r.id.nav_home: mfragment = getsupportfragmentmanager().findfragmentbytag("fragment_home"); if(!(mfragment!=null && mfragment.isvisible())){ mfragmentmanager.popbackstackimmediate("fragment_home", fragmentmanager.pop_back_stack_inclusive); mfragmenttransaction = mfragmentmanager.begintransaction(); mfragmenttransaction.replace(r.id.container, new homefragment(), "fragment_home").addtobackstack("fragment_home").commit(); } return true; case r.id.nav_account: mfragment = getsupportfragmentmanager().findfragmentbytag("fragment_account"); if(!(mfragment != null && mfragment.isvisible())){ mfragmentmanager.popbackstackimmediate("fragment_account", fragmentmanager.pop_back_stack_inclusive); mfragmenttransaction = mfragmentmanager.begintransaction(); mfragmenttransaction.replace(r.id.container, new accountfragment(), "fragment_account").addtobackstack("fragment_account").commit(); } return true; case r.id.nav_category: mfragment = getsupportfragmentmanager().findfragmentbytag("fragment_category"); if(!(mfragment != null && mfragment.isvisible())){ mfragmentmanager.popbackstackimmediate("fragment_category", fragmentmanager.pop_back_stack_inclusive); mfragmenttransaction = mfragmentmanager.begintransaction(); mfragmenttransaction.replace(r.id.container, new categoryfragment(), "fragment_category").addtobackstack("fragment_category").commit(); } return true; } return false; } @override public void onbackpressed() { if (mdrawerlayout.isdraweropen(gravitycompat.start)) { mdrawerlayout.closedrawer(gravitycompat.start); } else if (getsupportfragmentmanager().getbackstackentrycount() > 0) { getsupportfragmentmanager().popbackstack(); } else if (doublebacktoexitpressedonce) { finishaffinity(); } else { this.doublebacktoexitpressedonce = true; toast.maketext(this, "please again exit", toast.length_short).show(); new handler().postdelayed(new runnable() { @override public void run() { doublebacktoexitpressedonce = false; } }, 2000); } }
give me idea whats wrong code. appreciated.
for issue, recommend use viewpager instead of fragment back-stack. firstly, i'll tell why should not use fragment backstack. guess in code, whenever activity created. move first fragment instantly. example: - b - c - c - c - c - c or - b - c - -b -c - -c -b. remove backstack fragment said, whenever click fragment again create new one. here other way use viewpager, make ux better. first, customized own fragmentstatepageradapter
better performance
public abstract class smartfragmentstatepageradapter extends fragmentstatepageradapter { // sparse array keep track of registered fragments in memory private sparsearray<fragment> registeredfragments = new sparsearray<fragment>(); public smartfragmentstatepageradapter(fragmentmanager fragmentmanager) { super(fragmentmanager); } // register fragment when item instantiated @override public object instantiateitem(viewgroup container, int position) { fragment fragment = (fragment) super.instantiateitem(container, position); registeredfragments.put(position, fragment); return fragment; } // unregister when item inactive @override public void destroyitem(viewgroup container, int position, object object) { registeredfragments.remove(position); super.destroyitem(container, position, object); } // returns fragment position (if instantiated) public fragment getregisteredfragment(int position) { return registeredfragments.get(position); } }
let create customviewpager
public class customviewpager extends viewpager { public customviewpager(context context) { super(context); setmyscroller(); } public customviewpager(context context, attributeset attrs) { super(context, attrs); setmyscroller(); } @override public boolean onintercepttouchevent(motionevent event) { // never allow swiping switch between pages return false; } @override public boolean ontouchevent(motionevent event) { // never allow swiping switch between pages return false; } //down 1 added smooth scrolling private void setmyscroller() { try { class<?> viewpager = viewpager.class; field scroller = viewpager.getdeclaredfield("mscroller"); scroller.setaccessible(true); scroller.set(this, new myscroller(getcontext())); } catch (exception e) { e.printstacktrace(); } } public class myscroller extends scroller { public myscroller(context context) { super(context, new decelerateinterpolator()); } @override public void startscroll(int startx, int starty, int dx, int dy, int duration) { super.startscroll(startx, starty, dx, dy, 350 /*1 secs*/); } } }
put in xml
file this:
<your_package_name.customviewpager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" />
this adapter of viewpager:
public class viewpageradapter extends smartfragmentstatepageradapter { private static int num_items = 3; private basefragment mfragment1, mfragment2, mfragment3; public viewpageradapter(fragmentmanager fragmentmanager) { super(fragmentmanager); mfragment1= fragment1.newinstance(0, fragment_tag_1); mfragment2= fragment2.newinstance(1, fragment_tag_2); mfragment3= fragment3.newinstance(2, fragment_tag_3); } @override public fragment getitem(int position) { switch (position) { case 0: return mfragment1; case 1: return mfragment2; case 2: return mfragment3; default: return null; } } @override public int getcount() { return num_items; } @override public int getitemposition(object object) { return position_none; } @override public parcelable savestate() { return null; } }
in activity, let init in oncreateview()
mviewpager = (customviewpager) findviewbyid(r.id.viewpager); mviewpageradapter = new viewpageradapter(mfragmentmanager); mviewpager.setadapter(mviewpageradapter); mframelayout.setvisibility(view.gone); mviewpager.setvisibility(view.visible); mviewpager.setsaveenabled(true);
when click tab, need use
mviewpager.setcurrentitem(number_of_time);
Comments
Post a Comment