您的位置:首页 > 其它

Fragment中监听返回键

2015-06-15 11:36 281 查看
有些时候在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监听返回键 ,感谢这位博友。

点击下载代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: