java - Android BaseFragment class with multiple different fragment types -


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?

enter image description here

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