Fragment监听返回键

Activity可以通过重写onKeyDown(int keyCode, KeyEvent event),很容易的监听物理返回键事件,而Fragment并不能重写物理键监听事件。在一个Activity多个Fragment页面的应用中,很多时候有必要的监听每个Fragment返回事件,并对每个Fragment做特殊的数据处理。如果将每个Fragment的返回事件都在FragmentActivity中监听消费,那么其onBackPressed()的代码将会比较混乱;

@Override  
public void onBackPressed() {  
    if(selectedFragment.equals(fragmentA)) {  
        //  todo:事件处理 
    } else if(selectedFragment.equals(fragmentB)) {  
        //  todo:事件处理 
    } else if(selectedFragment.equals(fragmentC)) {  
        //  todo:事件处理
    } else {  
        // handle by activity  
        super.onBackPressed();  
    }  
}

那么有没有更好方法分离出各个Fragment的返回事件呢?答案是有的。

需要创建一个抽象类BackHandledFragment,继承于Fragment,该类有个抽象方法onBackPressed(),所有的BackHandledFragment子类都在onBackPressed()中实现自己对返回键的消费处理,onBackPressed()有boolean返回值,用于告诉FragmentActivity,当前的物理返回键是否被消费。

接下来如何告诉宿主FragmentActivity,当前的Fragment对象是哪个呢?以方便FragmentActivity调用当前Fragment对象的onBackPressed()方法。我们可以通过接口来通知宿主FragmentActivity;

public interface IFragmentBackHandled {
    abstract void setSelectedFragment(MyFragmentV4 selectedFragment);
}

定义了一个Fragment返回接口,在FragmentActivity中实现该接口,

public class ActivityMain extends MyFragmentActivity implements
        IFragmentBackHandled {
        private MyFragmentV4 iFragmentBackHandled;

    @Override
    public void setSelectedFragment(MyFragmentV4 selectedFragment) {
        iFragmentBackHandled = selectedFragment;
    }
}

接下来,在Fragment的onAttach中获取该接口对象,在Fragment的onStart()方法中调用setFragmentSelected()方法,告诉宿主FragmentActivity,当前栈顶的Fragment对象是哪个。

@Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if(activity instanceof IFragmentBackHandled){
            this.mBackHandled = (IFragmentBackHandled) activity;
        }
    }
        @Override
    public void onStart() {
        super.onStart();
        setSelected();
    }

    protected void setFragmentSelected(){
        mBackHandled.setSelectedFragment(this);
    }

如果用show,hide的方式显示/隐藏Fragment,需要在onHiddenChanged(boolean hidden) 中调用setFragmentSelected通知宿主绑定的Fragment对象,因为show/hide的方式并不会再调用onStart()方法。

然后宿主FragmentActivity就可以在onBackPressed()中对back事件进行判断处理,这里我的onBackPressed方法的返回值用于判断是否从当前的Fragment页面退出整个app应用,否则回退栈。

public class ActivityMain extends MyFragmentActivity implements
         IFragmentBackHandled {

    private MyFragmentV4 iFragmentBackHandled;

    @Override
    public void setSelectedFragment(MyFragmentV4 selectedFragment) {
        iFragmentBackHandled = selectedFragment;
    }

    @Override
    public void onBackPressed() {
        if (iFragmentBackHandled != null) {
            if (iFragmentBackHandled.isBackPressed() && getSupportFragmentManager()
                    .getBackStackEntryCount() > 0) {
                super.onBackPressed();
                return;
            }
            finish();
        }
    }
}

另外,网上还流传一些其他方法,比如在Fragment中通过getView()来绑定点击事件。

@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

                return true;

            }

            return false;
        }
    });
}

具体参考链接如下:
http://stackoverflow.com/questions/22552958/handling-back-press-when-using-fragments-in-android

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值