0

I have a BaseActivity() that have many activities and a BaseFragment() that have many fragments. Each activity contains 2-3 fragments and I need to make a generic method to handle each onBackPressed from all fragments (all - means all app screens) but this method should be in Base Fragment() (every fragment extends it). I supose that I'll need a kind of listener to tie OnBackPressed() from BaseActivity() to genericMethod() from BaseFragment()

Thanks in advice.

Choletski
  • 7,074
  • 6
  • 43
  • 64
  • 1
    Can you elaborate what kind of generic functionality you want to implement commonly among all fragments ? And FYI, `Fragment` class doesn't have `onBackPressed()` method ! You have to use Activity's `onBackPressed()` – Sharp Edge Aug 26 '15 at 11:49
  • I have a method that make server calls, but it doesn't metter, when I press back from all app screens to ri\un a method from BaseFragment() this is the point – Choletski Aug 26 '15 at 11:55
  • You can upvote and accept an answer which works for you, to show your appreciation. If none of the answers work then describe what you're facing now. – Sharp Edge Aug 27 '15 at 07:20

5 Answers5

1

@Choletski:

onBackPressed()

It will be called when the activity has detected the user's press of the back key. The default implementation simply finishes the current activity, but you can override this to do whatever you want.while overriding the default back button action as it is not suggested to change the android default user experience.

Override the onBackPressed() method and take the action inside this function.

@Override
    public void onBackPressed() {
        // Write your code here

        super.onBackPressed();
    }

How to implement onBackPressed() in Android Fragments?

Community
  • 1
  • 1
IntelliJ Amiya
  • 74,896
  • 15
  • 165
  • 198
1

The simplest solution rest to be a bit "hard programmed" in my case, like I mentioned in my question I need a method from BaseFragment() to handle all back press actions from all screens that means all fragments that extends this BaseFragment().

@Sharp Edge solution may be accepted but why to handle it in each SimpleActivity() that extends BaseActivity() if I can just add a single method in BaseFragment() and all simple activities that extends BaseActivity() will don't care about that.

@escape-llc solution is confused and not the expected one... I can handle it easier using EventBus or Otto and send from onResume() from each fragment to SimpleActivity(). So I'll receive the actual open fragment and I'll now what action to do when onBackPressed() is executed...

So, like I said, my solution is to use just a simple generic method in BaseFragment():

   public void doBackBtnPressedAction(View view) {
    view.setFocusableInTouchMode(true);
    view.requestFocus();

    view.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                if (keyCode == KeyEvent.KEYCODE_BACK) {

                    //logical part, in my case some server requests 

                    return true;
                }
            }
            return false;
        }
    });
}
Choletski
  • 7,074
  • 6
  • 43
  • 64
0

This is how i handled it when i had a webview in fragment and wanted to handle onBackPressed for the webview?

public class Tab2 extends Fragment {
ProgressBar progress;
WebView x;

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View v =inflater.inflate(R.layout.tab_2,container,false);
    x = (WebView)v.findViewById(R.id.webView);
    x.setOnKeyListener(new OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if(event.getAction() == KeyEvent.ACTION_DOWN)
            {
                WebView web = (WebView)v;
                switch (keyCode)
                {
                    case KeyEvent.KEYCODE_BACK:
                        if(web.canGoBack())
                        {
                            web.goBack();
                            return  true;
                        }
                        break;
                }
            }
            return false;
        }
    });
0

You have to make a custom Activity class for this.. and override its on onBackPressed() and add your logic in their. Then make sure wherever Fragments are used, you have to make the associated Activity sub class of this CustomActivity..

So whenever no matter on which Fragment user is, onBackPressed() of that Activity will be called and add super() to it.. so that it will call the base class's method and your code will run on each fragment.

example:

MyCustomActvity extends FragmentActivity{
  @Override
  public void onBackPressed(){

   // your logic here
   super.onBackPressed();
   }


}

Now You know that Fragments must have at least 1 Base Activity, so just override that Activity's onBackPressed()

MyActivity extends MyCustomActivity{

 // 3 fragments are called/replaced from this activity

 // other code

    @Override
    public void onBackPressed(){
     super.onBackPressed();  // it will invoke base class method and your code

    }


}

Just extend MyCustomActivity for the ones which use Fragments.

Sharp Edge
  • 4,144
  • 2
  • 27
  • 41
0

Here is a great way to handle it in a general fashion. We use it now in all of our fragment-based apps.

First create an interface for fragments to implement. This represents whether they want to handle the back key at all. If not, don't implement the interface.

public interface IHandleBackPressed {
    boolean handleBackPressed(Activity ax);
}

This is essentially a proxy for the activity's onBackPressed method.

Next, override the Activity.onBackPressed method with this boilerplate:

@Override
public void onBackPressed() {
    final Fragment fx = getFragmentManager().findFragmentById(R.id.content);
    if(fx != null) {
        if(fx instanceof IHandleBackPressed) {
            final IHandleBackPressed ihbp = (IHandleBackPressed)fx;
            if(ihbp.handleBackPressed(this)) {
                // we handled it
                return;
            }
        }
    }
    // onBackPressed unhandled by us
    super.onBackPressed();
}

This can be the same always. If you have multiple fragment areas, simply repeat the sequence for each one. If you have additional logic, integrate it before or after, but before you call super.onBackPressed to let the system take over (i.e. exit your activity).

Here is a sample of what a Fragment can do. This example uses a WebView and it wants to "use" the back key to manage the Back Stack of the WebView:

public class BrowseUrlFragment extends Fragment implements IHandleBackPressed {
    WebView wv;
    public boolean handleBackPressed(Activity ax) {
        if(wv != null && wv.canGoBack()) {
            wv.postDelayed(goback, 150);
            return true;
        }
        return false;
    }
}
escape-llc
  • 1,295
  • 1
  • 12
  • 25