Fragment中监听返回键

有些时候在Activity中监听的返回键,但此Activity中的Fragment并不想返回键实现同样的功能,所以需要Fragment中监听返回键。令人失望的是Fragment并不能直接对物理返回键进行监听,所以需要自己另外去进行代码实现。

下面的代码适合如下情况:一个Activity中实现了连续两次点击物理返回键退出应用程序,但此Activity中的Fragment物理返回键功能是从Fragment栈中移除此界面。

宿主FragmentActivity要实现的接口,以便确定当前屏幕可见的Fragment

public interface BackHandledInterface {

    public abstract void setSelectedFragment(BackHandledFragment selectedFragment);
}

主界面的FragmentActivity

public class MainActivity extends FragmentActivity implements BackHandledInterface{ 

    private BackHandledFragment mBackHandedFragment;

    private Button mBtn;

    /** 上次点击返回键的时间 */
    private long lastBackPressed;
    /** 上次点击返回键的时间 */
    private static final int QUIT_INTERVAL = 2000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.mBtn = (Button)findViewById(R.id.btn);
        this.mBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                MyFragment f = new MyFragment();
                FragmentManager fm = getSupportFragmentManager();
                FragmentTransaction ft = fm.beginTransaction();
                ft.replace(R.id.container, f);
                ft.addToBackStack("tag");
                ft.commit();
            }
        });
    }

    @Override
    public void setSelectedFragment(BackHandledFragment selectedFragment) {
        this.mBackHandedFragment = selectedFragment;
    }

    @Override
    public void onBackPressed() {
        if(mBackHandedFragment == null || !mBackHandedFragment.onBackPressed()){
            if(getSupportFragmentManager().getBackStackEntryCount() == 0){
                long backPressed = System.currentTimeMillis();
                if (backPressed - lastBackPressed > QUIT_INTERVAL) {
                    lastBackPressed = backPressed;
                    Toast.makeText(this, "再按一次退出", Toast.LENGTH_LONG).show();
                } else {
                    finish();
                    System.exit(0);
                }
            } else {
                getSupportFragmentManager().popBackStack();
            }
        }
    }
}

Fragment的基类,实现对物理返回键的监听

public abstract class BackHandledFragment extends Fragment { 

    protected BackHandledInterface mBackHandledInterface;

    /** * 所有继承BackHandledFragment的子类都将在这个方法中实现物理Back键按下后的逻辑 * FragmentActivity捕捉到物理返回键点击事件后会首先询问Fragment是否消费该事件 * 如果没有Fragment消息时FragmentActivity自己才会消费该事件 */
    protected abstract boolean onBackPressed();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(!(getActivity() instanceof BackHandledInterface)){
            throw new ClassCastException("Hosting Activity must implement BackHandledInterface");
        }else{
            this.mBackHandledInterface = (BackHandledInterface)getActivity();
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        //告诉FragmentActivity,当前Fragment在栈顶
        mBackHandledInterface.setSelectedFragment(this);
    }

}

显示在当前屏幕的Fragment

public class MyFragment extends BackHandledFragment { 

    private boolean hadIntercept;   

    @Override
    public View onCreateView(LayoutInflater inflater,
            @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return getLayoutInflater(savedInstanceState).inflate(R.layout.fragment_a, null);
    }

    @Override
    protected boolean onBackPressed() {
        if(hadIntercept){
            return false;
        }else{
            getFragmentManager().popBackStack();
            hadIntercept = true;
            return true;
        }
    }
}

如果要在Fragment中的物理返回键实现其他功能,则可根据此代码另行改进。

思路来源于另一位博友的优雅的让Fragment监听返回键 ,感谢这位博友。

点击下载代码

    原文作者:哆啦U梦
    原文地址: https://blog.csdn.net/u013952370/article/details/46502001
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞