How to implement onBackPressed() in Fragments?

2018-12-31 03:15发布

Is there a way in which we can implement onBackPressed() in Android Fragment similar to the way in which we implement in Android Activity?

As the Fragment lifecycle do not have onBackPressed(). Is there any other alternative method to over ride onBackPressed() in Android 3.0 fragments?

30条回答
公子世无双
2楼-- · 2018-12-31 03:48

this is my solution:

in MyActivity.java:

public interface OnBackClickListener {
        boolean onBackClick();
    }

    private OnBackClickListener onBackClickListener;

public void setOnBackClickListener(OnBackClickListener onBackClickListener) {
        this.onBackClickListener = onBackClickListener;
    }

@Override
    public void onBackPressed() {
        if (onBackClickListener != null && onBackClickListener.onBackClick()) {
            return;
        }
        super.onBackPressed();
    }

and in Fragment:

((MyActivity) getActivity()).setOnBackClickListener(new MyActivity.OnBackClickListener() {
    @Override
    public boolean onBackClick() {
        if (condition) {
            return false;
        }

        // some codes

        return true;
    }
});
查看更多
ら面具成の殇う
3楼-- · 2018-12-31 03:49

If you wanted that sort of functionality you would need to override it in your activity, and then add a YourBackPressed interface to all your fragments, which you call on the relevant fragment whenever the back button is pressed.

Edit: I'd like to append my previous answer.

If I were to do this today, I'd use a broadcast, or possibly a ordered broadcast if I expected other panels to update in unison to the master/main content panel.

LocalBroadcastManager in the Support Library can help with this, and you just send the broadcast in onBackPressed and subscribe in your fragments that care. I think that Messaging is a more decoupled implementation and would scale better, so it would be my official implementation recommendation now. Just use the Intent's action as a filter for your message. send your newly created ACTION_BACK_PRESSED, send it from your activity and listen for it in the relevant fragments.

查看更多
时光乱了年华
4楼-- · 2018-12-31 03:49
@Override
public void onResume() {
    super.onResume();

    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
                // handle back button
                replaceFragmentToBackStack(getActivity(), WelcomeFragment.newInstance(bundle), tags);

                return true;
            }

            return false;
        }
    });
}
查看更多
何处买醉
5楼-- · 2018-12-31 03:50

Do not implement ft.addToBackStack() method so that when you pressed back button your activity will be finished.

proAddAccount = new ProfileAddAccount();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, proAddAccount);
//fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
查看更多
美炸的是我
6楼-- · 2018-12-31 03:50

Very short and sweet answer:

getActivity().onBackPressed();

Explanation of whole scenario of my case:

I have FragmentA in MainActivity, I am opening FragmentB from FragmentA (FragmentB is child or nested fragment of FragmentA)

 Fragment duedateFrag = new FragmentB();
 FragmentTransaction ft  = getFragmentManager().beginTransaction();
 ft.replace(R.id.container_body, duedateFrag);
 ft.addToBackStack(null);
 ft.commit();

Now if you want to go to FragmentA from FragmentB you can simply put getActivity().onBackPressed(); in FragmentB.

查看更多
步步皆殇っ
7楼-- · 2018-12-31 03:51

In activity life cycle, always android back button deals with FragmentManager transactions when we used FragmentActivity or AppCompatActivity.

To handle the backstack we don't need to handle its backstack count or tag anything but we should keep focus while adding or replacing a fragment. Please find the following snippets to handle the back button cases,

    public void replaceFragment(Fragment fragment) {

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        if (!(fragment instanceof HomeFragment)) {
            transaction.addToBackStack(null);
        }
        transaction.replace(R.id.activity_menu_fragment_container, fragment).commit();
    }

Here, I won't add back stack for my home fragment because it's home page of my application. If add addToBackStack to HomeFragment then app will wait to remove all the frament in acitivity then we'll get blank screen so I'm keeping the following condition,

if (!(fragment instanceof HomeFragment)) {
            transaction.addToBackStack(null);
}

Now, you can see the previously added fragment on acitvity and app will exit when reaching HomeFragment. you can also look on the following snippets.

@Override
public void onBackPressed() {

    if (mDrawerLayout.isDrawerOpen(Gravity.LEFT)) {
        closeDrawer();
    } else {
        super.onBackPressed();
    }
}
查看更多
登录 后发表回答