android - Implement back navigation with DrawerLayout and AppCompatActivity without DrawerToggle -
i've been searching , thinking how implement desire behaviour want when switching , forth between fragments when using navigation drawer. documentation says: when using fragments in app, individual fragmenttransaction objects may represent context changes should added stack. example, if implementing master/detail flow on handset swapping out fragments, should ensure pressing button on detail screen returns user master screen
so in app have mainactivity controls , navigation layout within can change between predefined options. view when launch app
when click on item in navigation drawer opens new fragment replaces main_content follows:
at point behaviour correct one, if want change options need open navigation drawer again toggle between menu options.
this main activity (notice there no drawer toggle)
mainactivity.java
public class mainactivity extends appcompatactivity { actionbardrawertoggle mdrawertoggle; private drawerlayout drawerlayout; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); msnackbarview = findviewbyid(r.id.mycoordinatorlayout); settoolbar(); // set toolbar como action bar if (savedinstancestate != null) { mcurrentselectedposition = savedinstancestate.getint(state_selected_position); mfromsavedinstancestate = true; } drawerlayout = (drawerlayout) findviewbyid(r.id.drawer_layout); navigationview navigationview = (navigationview) findviewbyid(r.id.nav_view); if (navigationview != null) { setupdrawercontent(navigationview); } drawertitle = getresources().getstring(r.string.app_name); if (savedinstancestate == null) { selectitem(drawertitle, mcurrentselectedposition); } } private void settoolbar() { toolbar toolbar = (toolbar) findviewbyid(r.id.toolbar); setsupportactionbar(toolbar); final actionbar ab = getsupportactionbar(); if (ab != null) { // poner ícono del drawer toggle ab.sethomeasupindicator(r.drawable.ic_menu); ab.setdisplayhomeasupenabled(true); } } private void setupdrawercontent(final navigationview navigationview) { navigationview.setnavigationitemselectedlistener( new navigationview.onnavigationitemselectedlistener() { @override public boolean onnavigationitemselected(menuitem menuitem) { // marcar item presionado menuitem.setchecked(true); // crear nuevo fragmento string title = menuitem.gettitle().tostring(); int id = menuitem.getitemid(); selectitem(title, id); return true; } } ); } @override public boolean oncreateoptionsmenu(menu menu) { if (!drawerlayout.isdraweropen(gravitycompat.start)) { getmenuinflater().inflate(r.menu.menu_main, menu); return true; } return super.oncreateoptionsmenu(menu); } @override public boolean onoptionsitemselected(menuitem item) { switch (item.getitemid()) { case android.r.id.home: drawerlayout.opendrawer(gravitycompat.start); return true; } return super.onoptionsitemselected(item); } private void selectitem(string title, int id) { bundle args = new bundle(); args.putstring(placeholderfragment.arg_section_title, title); fragment fragment = placeholderfragment.newinstance(title); fragment.setarguments(args); fragmentmanager fragmentmanager = getsupportfragmentmanager(); fragmentmanager .begintransaction() .replace(r.id.main_content, fragment) .commit(); switch (id) { case r.id.nav_localizacion: //snackbar.make(msnackbarview, r.string.menu_localization, snackbar.length_short).show(); mcurrentselectedposition = 0; localizacionfragment fragment_localizacion = new localizacionfragment(); // fragmentmanager = getsupportfragmentmanager(); snackbar.make(msnackbarview, r.string.menu_localization, snackbar.length_short).show(); fragmentmanager .begintransaction() .replace(r.id.main_content, fragment_localizacion) .commit(); break; case r.id.nav_productos: snackbar.make(msnackbarview, r.string.menu_productos, snackbar.length_short).show(); mcurrentselectedposition = 1; fragmentmanager .begintransaction() .replace(r.id.main_content, fragment) .commit(); break; case r.id.nav_consejos: snackbar.make(msnackbarview, r.string.menu_consejos, snackbar.length_short).show(); mcurrentselectedposition = 3; consejosfragment fragment_consejo = new consejosfragment(); fragmentmanager .begintransaction() .replace(r.id.main_content, fragment_consejo) .commit(); break; default: break; } drawerlayout.closedrawers(); // cerrar drawer settitle(title); // título actual } }
i don't use hamburger icon because hides under navigation layout, here thing. when click on "recetas" in recycle view open new fragment (replace) want show caret icon , give proper navigation app.
here code of "consejos" fragment class
consejos.java
public class consejosfragment extends fragment { recyclerview mrecycler; consejosadapter madapter; fragmentactivity mactivity; @override public void onattach(activity activity) { super.onattach(activity); this.mactivity = (fragmentactivity) activity; setretaininstance(true); } @override public void onactivitycreated(bundle savedinstancestate) { super.onactivitycreated(savedinstancestate); sethasoptionsmenu(true); } @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { list items = new arraylist(); items.add(new consejosinfo("recetas", r.drawable.icon_recetas)); /* inflamos el layout */ view v = inflater.inflate(r.layout.consejos_layout_recycler, container, false); /* obtenemos el recycle */ mrecycler = (recyclerview) v.findviewbyid(r.id.recycler_consejos); /* creamos el adaptador */ madapter = new consejosadapter(mactivity, items); /* set click en adapter */ return v; } @override public void onviewcreated(view view, bundle savedinstancestate) { super.onviewcreated(view, savedinstancestate); mrecycler.sethasfixedsize(true); mrecycler.setlayoutmanager(new linearlayoutmanager(getactivity())); mrecycler.setadapter(madapter); } }
and adapter recyclerview use , handles click on item inside:
adapter.java
public class consejosadapter extends recyclerview.adapter<consejosadapter.consejosviewholder> { private list<consejosinfo> _items = new arraylist<consejosinfo>(); private final fragmentactivity mactivity; private context context; public consejosadapter(fragmentactivity mactivity, list<consejosinfo> items) { this._items = items; this.mactivity = mactivity; } @override public int getitemcount() { return _items.size(); } @override public consejosviewholder oncreateviewholder(viewgroup viewgroup, int viewtype) { view v = layoutinflater.from(viewgroup.getcontext()).inflate(r.layout.cardview_consejos, viewgroup, false); return new consejosviewholder(v); } @override public void onbindviewholder(consejosviewholder viewholder, int position) { viewholder.imagen.setimageresource(_items.get(position).get_imagen()); viewholder.nombre.settext(_items.get(position).get_nombre()); } public class consejosviewholder extends recyclerview.viewholder implements view.onclicklistener { public imageview imagen; public textview nombre; public consejosviewholder(final view itemview) { super(itemview); imagen = (imageview) itemview.findviewbyid(r.id.consejos_imagen); nombre = (textview) itemview.findviewbyid(r.id.consejos_nombre); itemview.setonclicklistener(this); } @override public void onclick(view v) { recetasfragment recetasfragment = new recetasfragment(); fragmentmanager fragmentmanager = mactivity.getsupportfragmentmanager(); fragmentmanager .begintransaction() .replace(r.id.main_content, recetasfragment) .addtobackstack(null) .commit(); } } }
in consejos adapter added backstack fragment before calling new fragment (inside fragment) , changes behaviour of button, before if press button closes app takes consejos fragment, want add caret , make same operation when click button don't know how achieve it.
please feel free ask more code
thank much
i give full answer: use interfaces communicate mainactivity
recetasfragment
can enable , disable navigation button.
recetasfragment
class:
import android.app.activity; import android.os.bundle; import android.support.v4.app.fragment; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; /** * created hema on 8/19/2015. */ public class recetasfragment extends fragment { private communicatewithactivity mwithactivity; public recetasfragment() { } @override public void onattach(activity activity) { super.onattach(activity); try { mwithactivity = (communicatewithactivity) activity; // mainactivity must implement communicatewithactivity interface. mwithactivity.enablenavigationback(true); // enable navigation here. } catch (classcastexception e) { throw new classcastexception(activity.tostring() + " must implement communicatewithactivity"); } } @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { return inflater.inflate(r.layout.fragment_recetas, container, false); } @override public void ondestroy() { super.ondestroy(); mwithactivity.enablenavigationback(false); // disable navigation here, restore menu icon. } public interface communicatewithactivity { void enablenavigationback(boolean enable);// implement method in mainactivity class. } }
and in mainactivity
class implement communicatewithactivity
interface, modify mainactivity
class (only required modifications):
import android.support.v7.app.appcompatactivity; import android.os.bundle; import android.support.v7.widget.toolbar; import android.view.menu; import android.view.menuitem; import android.view.view; public class mainactivity extends appcompatactivity implements recetasfragment.communicatewithactivity { private toolbar mtoolbar; private drawerlayout drawerlayout; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); mtoolbar = (toolbar) findviewbyid(r.id.toolbar); setsupportactionbar(mtoolbar); mtoolbar.setnavigationicon(r.drawable.ic_menu); msnackbarview = findviewbyid(r.id.mycoordinatorlayout); if (savedinstancestate != null) { mcurrentselectedposition = savedinstancestate.getint(state_selected_position); mfromsavedinstancestate = true; } drawerlayout = (drawerlayout) findviewbyid(r.id.drawer_layout); navigationview navigationview = (navigationview) findviewbyid(r.id.nav_view); if (navigationview != null) { setupdrawercontent(navigationview); } drawertitle = getresources().getstring(r.string.app_name); if (savedinstancestate == null) { selectitem(drawertitle, mcurrentselectedposition); } } private void setupdrawercontent(final navigationview navigationview) { navigationview.setnavigationitemselectedlistener( new navigationview.onnavigationitemselectedlistener() { @override public boolean onnavigationitemselected(menuitem menuitem) { // marcar item presionado menuitem.setchecked(true); // crear nuevo fragmento string title = menuitem.gettitle().tostring(); int id = menuitem.getitemid(); selectitem(title, id); return true; } } ); } @override public boolean oncreateoptionsmenu(menu menu) { if (!drawerlayout.isdraweropen(gravitycompat.start)) { getmenuinflater().inflate(r.menu.menu_main, menu); return true; } return super.oncreateoptionsmenu(menu); } @override public boolean onoptionsitemselected(menuitem item) { switch (item.getitemid()) { case android.r.id.home: drawerlayout.opendrawer(gravitycompat.start); return true; } return super.onoptionsitemselected(item); } private void selectitem(string title, int id) { bundle args = new bundle(); args.putstring(placeholderfragment.arg_section_title, title); fragment fragment = placeholderfragment.newinstance(title); fragment.setarguments(args); fragmentmanager fragmentmanager = getsupportfragmentmanager(); fragmentmanager .begintransaction() .replace(r.id.main_content, fragment) .commit(); switch (id) { case r.id.nav_localizacion: //snackbar.make(msnackbarview, r.string.menu_localization, snackbar.length_short).show(); mcurrentselectedposition = 0; localizacionfragment fragment_localizacion = new localizacionfragment(); // fragmentmanager = getsupportfragmentmanager(); snackbar.make(msnackbarview, r.string.menu_localization, snackbar.length_short).show(); fragmentmanager .begintransaction() .replace(r.id.main_content, fragment_localizacion) .commit(); break; case r.id.nav_productos: snackbar.make(msnackbarview, r.string.menu_productos, snackbar.length_short).show(); mcurrentselectedposition = 1; fragmentmanager .begintransaction() .replace(r.id.main_content, fragment) .commit(); break; case r.id.nav_consejos: snackbar.make(msnackbarview, r.string.menu_consejos, snackbar.length_short).show(); mcurrentselectedposition = 3; consejosfragment fragment_consejo = new consejosfragment(); fragmentmanager .begintransaction() .replace(r.id.main_content, fragment_consejo) .commit(); break; default: break; } drawerlayout.closedrawers(); // cerrar drawer settitle(title); // título actual } @override public void enablenavigationback(boolean enable) { if(enable) { // enable navigation button here mtoolbar.setnavigationicon(r.drawable.abc_ic_ab_back_mtrl_am_alpha); mtoolbar.setnavigationonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { // on navigation button clicked. if(getsupportfragmentmanager().getbackstackentrycount() > 0) { // check if there fragments in backstack. getsupportfragmentmanager().popbackstack(); // popbackstack. } else { // can implement part want. return; } } }); } else { mtoolbar.setnavigationicon(r.drawable.ic_menu); mtoolbar.setnavigationonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { if(drawerlayout != null) { drawerlayout.opendrawer(gravity.left); } } }); } } }
please let me know if there don't understand.
Comments
Post a Comment