我的活动中有一些碎片

[1], [2], [3], [4], [5], [6]

如果当前活动片段是[2],那么在返回按钮上按下我必须从[2]返回到[1],否则什么也不做。

最好的做法是什么?

编辑:应用程序不能从[3]…[6]返回[2]


当前回答

对于那些谁使用静态片段

在这种情况下,如果你有一个静态片段,那么它会更可取。 为片段创建一个实例对象

private static MyFragment instance=null;

在MyFragment的onCreate()中初始化该实例

  instance=this;

也可以创建一个函数来获取Instance

 public static MyFragment getInstance(){
   return instance;
}

也可以创建函数

public boolean allowBackPressed(){
    if(allowBack==true){
        return true;
    }
    return false;
}


 //allowBack is a boolean variable that will be set to true at the action 
 //where you want that your backButton should not close activity. In my case I open 
 //Navigation Drawer then I set it to true. so when I press backbutton my 
 //drawer should be get closed

public void performSomeAction(){
    //.. Your code
    ///Here I have closed my drawer
}

在你能做的活动中

@Override
public void onBackPressed() {

    if (MyFragment.getInstance().allowBackPressed()) { 
        MyFragment.getInstance().performSomeAction();
    }
    else{
        super.onBackPressed();
    }
}

其他回答

如果你重写了片段视图的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;
            }
        });

将addToBackStack()添加到片段事务中,然后使用下面的代码为片段实现反向导航

getSupportFragmentManager().addOnBackStackChangedListener(
    new FragmentManager.OnBackStackChangedListener() {
        public void onBackStackChanged() {
            // Update your UI here.
        }
    });

我正在与SlidingMenu和Fragment一起工作,在这里展示我的案例,希望能帮助到别人。

按[后退]键时的逻辑:

When SlidingMenu shows, close it, no more things to do. Or when 2nd(or more) Fragment showing, slide back to previous Fragment, and no more things to do. SlidingMenu not shows, current Fragment is #0, do the original [Back] key does. public class Main extends SherlockFragmentActivity { private SlidingMenu menu=null; Constants.VP=new ViewPager(this); //Some stuff... @Override public void onBackPressed() { if(menu.isMenuShowing()) { menu.showContent(true); //Close SlidingMenu when menu showing return; } else { int page=Constants.VP.getCurrentItem(); if(page>0) { Constants.VP.setCurrentItem(page-1, true); //Show previous fragment until Fragment#0 return; } else {super.onBackPressed();} //If SlidingMenu is not showing and current Fragment is #0, do the original [Back] key does. In my case is exit from APP } } }

如果你想处理硬件返回键事件,那么你必须在Fragment的onActivityCreated()方法中执行以下代码。

你还需要检查Action_Down或Action_UP事件。如果你不检查,那么onKey()方法将调用2次。

同样,如果你的rootview(getView())将不包含焦点,那么它将无法工作。如果你点击了任何控件,那么你需要再次使用getView().requestFocus()给rootview的焦点;在此之后,只有onKeydown()将调用。

getView().setFocusableInTouchMode(true);
getView().requestFocus();

getView().setOnKeyListener(new OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    if (keyCode == KeyEvent.KEYCODE_BACK) {
                        Toast.makeText(getActivity(), "Back Pressed", Toast.LENGTH_SHORT).show();
                    return true;
                    }
                }
                return false;
            }
        });

对我来说很好。

我认为最简单的方法是创建一个接口,并在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();
}