Activity can easily get a physical return key to listen to events, but fragment can't. Assuming that the fragmentactivity has three fragment, the average Android user expects to click the Back button to return to the fragmentactivity layer. Of course, we can put each fragment corresponding transaction into Backstack, but if each fragment has a special consumption for the return event, then Fragmentactivity () in onbackpressed The code in will be confusing, for example:
@Override Public voidonbackpressed () {if(Selectedfragment.equals (Fragmenta) &&Fragmenta.hasexpandedrow ()) {Fragmenta.collapserow (); } Else if(Selectedfragment.equals (Fragmenta) &&Fragmenta.isshowingloginview ()) {Fragmenta.hideloginview (); } Else if(Selectedfragment.equals (Fragmenta)) {popbackstack (); } Else if(Selectedfragment.equals (FRAGMENTB) &&Fragmentb.hascondition1 ()) {Fragmentb.reversecondition1 (); } Else if(Selectedfragment.equals (FRAGMENTB) &&Fragmentb.hascondition2 ()) {Fragmentb.reversecondition2 (); } Else if(Selectedfragment.equals (FRAGMENTB)) {popbackstack (); } Else { //Handle by Activitysuper.onbackpressed (); }}
This is obviously intolerable for a program ape with code cleanliness, and later found an elegant solution.
First, create an abstract class backhandledfragment, which has an abstract method onbackpressed (), The subclasses of all backhandledfragment handle their consumption logic for the back event in the Onbackpressed method. Onbackpressed returns a Boolean value that the host Fragmentactivity will use to determine whether the child fragment has a consumption back event based on the method's return value. In addition, the host Fragmentactivity maintains a reference to the current fragment, and when the user presses the back key, the host activity will determine whether the current fragment needs to consume the event or consume it without fragment consumption.
Public Abstract classBackhandledfragment extends Fragment {protectedBackhandledinterface Mbackhandledinterface; /** * All inherited backhandledfragment subclasses will implement the physical back key pressed after the logical * fragmentactivity Snap to the physical return key Click event will first ask fragment whether to consume the event * If there is no fragment message, Fragmentactivity will only consume the event*/ protected Abstractboolean onbackpressed (); @Override Public voidonCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); if(!(getactivity () instanceof Backhandledinterface)) { Throw NewClassCastException ("Hosting Activity must implement Backhandledinterface"); }Else{ This. Mbackhandledinterface =(Backhandledinterface) getactivity (); }} @Override Public voidOnStart () {Super.onstart (); //tell Fragmentactivity that the current fragment is at the top of the stackMbackhandledinterface.setselectedfragment ( This); } }
The host fragmentactivity needs to inherit Backhandledintegerface, which the child fragment tells the host fragmentactivity itself is the fragment that is visible on the current screen.
Public Interface Backhandledinterface { publicabstractvoid setselectedfragment ( Backhandledfragment selectedfragment);}
Therefore, the OnCreate in fragment determines whether the host fragmentactivity has inherited the interface. This interface is called in Fragment's OnStart () method to tell the host that fragmentactivity itself is the fragment that is visible on the current screen.
The host fragmentactivity can then judge the back event in the Onbackpressed () method.
Public classMainactivity extends fragmentactivity implements backhandledinterface{Privatebackhandledfragment mbackhandedfragment; PrivateBoolean hadintercept; @Override Public voidsetselectedfragment (backhandledfragment selectedfragment) { This. mbackhandedfragment =selectedfragment; } @Override Public voidonbackpressed () {if(Mbackhandedfragment = =NULL|| !mbackhandedfragment.onbackpressed ()) { if(Getsupportfragmentmanager (). Getbackstackentrycount () = =0) {super.onbackpressed (); }Else{Getsupportfragmentmanager (). Popbackstack (); } } }}
Sample program GitHub link.
Android Graceful Let fragment listen back key