美文网首页
【转】监听Fragment返回键事件,两种方法的区别

【转】监听Fragment返回键事件,两种方法的区别

作者: Solang | 来源:发表于2019-06-22 19:18 被阅读0次

百度了一下找到了两种方法,并做了一下试验,发现两种方法的效果是不一样的。
(大家不试验一下也许就没有发现)

1. 在Fragment中onResume监听返回键事件

@Override
public void onResume() {
    super.onResume();
    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View view, int i, KeyEvent keyEvent) {
            if(keyEvent.getAction() == KeyEvent.ACTION_DOWN && i == KeyEvent.KEYCODE_BACK){
                Toast.makeText(getActivity(), "按了返回键", Toast.LENGTH_SHORT).show();
                return true;
            }
            return false;
        }
    });
}

setFocusableInTouchMode(true)和requestFocus()是让主界面获取焦点
这两行是很关键的,如果没有这两行,OnKeyListener的事件无法监听。
如果OnKeyListener中return true代表返回事件只执行我们指定的代码;
如果OnKeyListener中return false代表返回事件指定我们指定的代码后,仍然执行默认的事件(默认的事件就是返回上一个页面)
效果图:

image image

问题来了:让主界面获取焦点,那万一界面有EditText等控件抢了焦点呢?
那焦点就不在界面上了,按“返回键”后无法执行OnKeyListener中指定的代码。虽然有人提出了解决的方法,不过还是觉得考虑的情况不够全面。于是我决定使用第二种方法

image image

2. 优雅的方法

①先定义接口BackHandleInterface
public interface BackHandleInterface {

    void onSelectedFragment(BackHandleFragment backHandleFragment);

}

②定义公用的Fragment
public abstract class BackHandleFragment extends Fragment {

    private BackHandleInterface backHandleInterface;

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

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(getActivity() instanceof BackHandleInterface){
            this.backHandleInterface = (BackHandleInterface)getActivity();
        }else{
            throw new ClassCastException("Hosting Activity must implement BackHandledInterface");
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        backHandleInterface.onSelectedFragment(this);
    }
}

③需要实现监听的Fragment的Activity实现接口

主要的是onSelectedFragment()onBackPressed()其他方法可以忽略

public class EdittextActivity extends AppCompatActivity implements BackHandleInterface {

    private BackHandleFragment backHandleFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_layout);
        addFragment(R.id.fragmentContainer, new EdittextFragment());
    }

    public void addFragment(int containerViewId, Fragment fragment){
        final FragmentTransaction transaction = this.getSupportFragmentManager().beginTransaction();
        transaction.add(containerViewId, fragment);
        transaction.commit();
    }

    @Override
    public void onSelectedFragment(BackHandleFragment backHandleFragment) {
        this.backHandleFragment = backHandleFragment;
    }

    @Override
    public void onBackPressed() {
        //if判断里面就调用了来自Fragment的onBackPressed()
        //一样!!,如果onBackPressed是返回false,就会进入条件内进行默认的操作
        if(backHandleFragment == null || !backHandleFragment.onBackPressed()){
            if(getSupportFragmentManager().getBackStackEntryCount() == 0){
                super.onBackPressed();
            }else{
                getSupportFragmentManager().popBackStack();
            }
        }
    }
}

④需要监听的Fragment
public class EdittextFragment extends BackHandleFragment {

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_edittext, container, false);
        return view;
    }

    @Override
    public boolean onBackPressed() {
        Toast.makeText(getActivity(), "按了返回键", Toast.LENGTH_SHORT).show();
        return true;//因为这里return true 所以不会返回上一个页面,方便我截图
    }
}

image

总结

第一种方法如果是在简单的页面就可以简单的实现监听返回键事件,
第二种方法就可以在比较复杂,有可能会抢焦点的页面用会好一点。

参考资料:(感谢大神的贡献)

优雅的让Fragment监听返回键
http://stackoverflow.com/questions/22552958/handling-back-press-when-using-fragments-in-android

作者:欢乐的乐
链接:https://www.jianshu.com/p/6e31ff8161c2
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

相关文章

网友评论

      本文标题:【转】监听Fragment返回键事件,两种方法的区别

      本文链接:https://www.haomeiwen.com/subject/iiivqctx.html