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监听返回键 ,感谢这位博友。

点击下载代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值