我的活动中有一些碎片
[1], [2], [3], [4], [5], [6]
如果当前活动片段是[2],那么在返回按钮上按下我必须从[2]返回到[1],否则什么也不做。
最好的做法是什么?
编辑:应用程序不能从[3]…[6]返回[2]
我的活动中有一些碎片
[1], [2], [3], [4], [5], [6]
如果当前活动片段是[2],那么在返回按钮上按下我必须从[2]返回到[1],否则什么也不做。
最好的做法是什么?
编辑:应用程序不能从[3]…[6]返回[2]
当前回答
如果你重写了片段视图的onKey方法,你需要:
view.setFocusableInTouchMode(true);
view.requestFocus();
view.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
Log.i(tag, "keyCode: " + keyCode);
if( keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
Log.i(tag, "onKey Back listener is working!!!");
getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
return true;
}
return false;
}
});
其他回答
在看了所有的解决方案后,我意识到有一个更简单的解决方案。
在你的活动的onBackPressed()托管你所有的片段,找到你想要防止反压的片段。如果找到了,就返回。那么popBackStack将永远不会发生在这个片段上。
@Override
public void onBackPressed() {
Fragment1 fragment1 = (Fragment1) getFragmentManager().findFragmentByTag(“Fragment1”);
if (fragment1 != null)
return;
if (getFragmentManager().getBackStackEntryCount() > 0){
getFragmentManager().popBackStack();
}
}
我认为最简单的方法是创建一个接口,并在Activity中检查片段是否属于接口类型,如果是,则调用它的方法来处理弹出。下面是要在片段中实现的接口。
public interface BackPressedFragment {
// Note for this to work, name AND tag must be set anytime the fragment is added to back stack, e.g.
// getActivity().getSupportFragmentManager().beginTransaction()
// .replace(R.id.fragment_container, MyFragment.newInstance(), "MY_FRAG_TAG")
// .addToBackStack("MY_FRAG_TAG")
// .commit();
// This is really an override. Should call popBackStack itself.
void onPopBackStack();
}
下面是如何实现它。
public class MyFragment extends Fragment implements BackPressedFragment
@Override
public void onPopBackStack() {
/* Your code goes here, do anything you want. */
getActivity().getSupportFragmentManager().popBackStack();
}
在你的Activity中,当你处理弹出时(可能在onBackPressed和onOptionsItemSelected中),使用这个方法弹出backstack:
public void popBackStack() {
FragmentManager fm = getSupportFragmentManager();
// Call current fragment's onPopBackStack if it has one.
String fragmentTag = fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 1).getName();
Fragment currentFragment = getSupportFragmentManager().findFragmentByTag(fragmentTag);
if (currentFragment instanceof BackPressedFragment)
((BackPressedFragment)currentFragment).onPopBackStack();
else
fm.popBackStack();
}
或者你可以使用getSupportFragmentManager().getBackStackEntryCount()来检查要做什么:
@Override
public void onBackPressed() {
logger.d("@@@@@@ back stack entry count : " + getSupportFragmentManager().getBackStackEntryCount());
if (getSupportFragmentManager().getBackStackEntryCount() != 0) {
// only show dialog while there's back stack entry
dialog.show(getSupportFragmentManager(), "ConfirmDialogFragment");
} else if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
// or just go back to main activity
super.onBackPressed();
}
}
如果您管理将每个事务添加到后退堆栈的流程,那么您可以这样做,以便在用户按后退按钮时显示上一个片段(您也可以映射home按钮)。
@Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0)
getFragmentManager().popBackStack();
else
super.onBackPressed();
}
当你在Fragments之间转换时,调用addToBackStack()作为FragmentTransaction的一部分:
FragmentTransaction tx = fragmentManager.beginTransation();
tx.replace( R.id.fragment, new MyFragment() ).addToBackStack( "tag" ).commit();
如果你需要更详细的控制(例如,当一些片段可见时,你想要抑制返回键),你可以在你的片段的父视图上设置一个OnKeyListener:
//You need to add the following line for this solution to work; thanks skayred
fragment.getView().setFocusableInTouchMode(true);
fragment.getView().requestFocus();
fragment.getView().setOnKeyListener( new OnKeyListener()
{
@Override
public boolean onKey( View v, int keyCode, KeyEvent event )
{
if( keyCode == KeyEvent.KEYCODE_BACK )
{
return true;
}
return false;
}
} );