i created base fragment class handles setting toolbar title, registering when fragment attached, setting menu icons , few other things. issue i've decided use preferencesfragmentcompat settings fragment , cant extend both basefragment , androids preferencesfragmentcompat. using interface here wouldn't because basefragment has lot of functionality, , don't want duplicate each of fragment classes. extend 2 classes, in 2 seperate files because both extend off androids fragment class, dont see how possible. there better way of doing this?
basefragment:
public abstract class basefragment extends fragment { protected view rootview; protected appsettings settings; protected layoutinflater inflater; public static void startfragment(activity activity, basefragment newfragment) { fragmentmanager fragmanager = ((appcompatactivity) activity).getsupportfragmentmanager(); basefragment currentfragment = (basefragment) fragmanager.findfragmentbyid(r.id.fragment_container); // start transactions fragmenttransaction transaction = fragmanager.begintransaction(); transaction.replace(r.id.fragment_container, newfragment); // if there fragment want on backstack if (currentfragment != null) { transaction.addtobackstack(null); } // show transaction.commit(); } @targetapi(21) private void lockmode(boolean start) { if (android.os.build.version.sdk_int >= 16) { if (start) { getactivity().startlocktask(); } else { getactivity().stoplocktask(); } } } @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); // reference app settings settings = appsettings.getinstance(getactivity()); // don't want keyboard stay open between fragments hidekeyboard(); actionbar actionbar = ((appcompatactivity) getactivity()).getsupportactionbar(); if (actionbar != null) { if (toolbarelevation()) { actionbar.setelevation(4 * getactivity().getresources().getdisplaymetrics().density); } else { actionbar.setelevation(0); } } sethasoptionsmenu(true); } @override public void onresume() { super.onresume(); // set title toolbar toolbar = (toolbar) getactivity().findviewbyid(r.id.toolbar); toolbar.settitle(gettitle()); // enable home button in action bar ((appcompatactivity) getactivity()).getsupportactionbar().setdisplayshowhomeenabled(true); // change home button icon menu or if (showupnavigation()) { toolbar.setnavigationicon(r.drawable.ic_navigation_back_white); } else { toolbar.setnavigationicon(r.drawable.ic_menu_white); } if (isappinlocktaskmode() == true && pinnedmode() == false) { lockmode(false); } setdrawermenu(); } public boolean getauthrequired() { return true; } public boolean isbackallowed() { return true; } public boolean toolbarelevation() { return true; } public string gettitle() { return "isoped"; } public boolean pinnedmode() { return false; } public boolean showupnavigation() { return false; } public void hidekeyboard() { inputmethodmanager inputmanager = (inputmethodmanager) getactivity().getsystemservice(context.input_method_service); // check if no view has focus: view v = getactivity().getcurrentfocus(); if (v == null) { return; } inputmanager.hidesoftinputfromwindow(v.getwindowtoken(), 0); } public void setdrawermenu() { navigationview navigationview = (navigationview) getactivity().findviewbyid(r.id.drawer_navigation); integer menuid = null; integer currentmenuid = null; if (settings.istype(appsettings.types.personal)) { menuid = r.menu.drawer_personal; } else if (settings.istype(appsettings.types.professional)) { if (getauthrequired() == true) { menuid = r.menu.drawer_professional_locked; } else { menuid = r.menu.drawer_professional_unlocked; } } if (menuid != null) { if (navigationview.gettag() != null) { currentmenuid = (integer) navigationview.gettag(); } if (currentmenuid == null || navigationview.getmenu().size() == 0 || currentmenuid != menuid) { navigationview.getmenu().clear(); navigationview.inflatemenu(menuid); navigationview.settag(integer.valueof(menuid)); } } } @override public void oncreateoptionsmenu(menu menu, menuinflater inflater) { super.oncreateoptionsmenu(menu, inflater); menu.clear(); if (settings.istype(appsettings.types.professional) && pinnedmode() && false == isappinlocktaskmode()) { inflater.inflate(r.menu.pin_menu, menu); } } @override public boolean onoptionsitemselected(menuitem item) { drawerlayout drawer = (drawerlayout) getactivity().findviewbyid(r.id.drawer_layout); switch (item.getitemid()) { case android.r.id.home: if (showupnavigation()) { getactivity().onbackpressed(); } else { drawer.opendrawer(gravitycompat.start); } return true; case r.id.menu_pin: if (isappinlocktaskmode()) { pindialog dialog = new pindialog((appcompatactivity) getactivity(), new navigationcallback((appcompatactivity) getactivity()) { @override public void run() { lockmode(false); } }); dialog.show(); } else { lockmode(true); } return true; } return super.onoptionsitemselected(item); } private boolean isappinlocktaskmode() { activitymanager activitymanager; activitymanager = (activitymanager) getactivity().getsystemservice(context.activity_service); if (build.version.sdk_int >= build.version_codes.m) { // sdk version 23 , above. return activitymanager.getlocktaskmodestate() != activitymanager.lock_task_mode_none; } if (build.version.sdk_int >= build.version_codes.lollipop) { // when sdk version >= 21. api deprecated in 23. return activitymanager.isinlocktaskmode(); } return false; } }
this nice example, should apply joshua bloch's "favor composition on inheritance" idiom.
you can delegate logic have applied basefragment
class fragmenthelper
:
public class fragmenthelper { private final fragment fragment; public fragmenthelper(fragment fragment) { this.fragment = fragment; } public void create(bundle bundle) { // `basefragment`'s code goes here } public void resume() { // `basefragment`'s code goes here } ... }
now in basefragment:
public class basefragment { private fragmenthelper fragmenthelper; @override public void oncreate(@nullable bundle savedinstancestate) { super.oncreate(savedinstancestate); ... fragmenthelper = new fragmenthelper(this); fragmenthelper.create(savedinstancestate); } @override public void onresume() { fragmenthelper.resume(); } }
and same should applied class extending preferencefragment
.
thus, you'd evade code duplication.
reference:
- joshua bloch - effective java 2nd edition, item 16.
Comments
Post a Comment