我的活动中有一些碎片

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

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

最好的做法是什么?

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


当前回答

我们创建了一个小的库来处理多个片段和/或活动中的背压。使用就像在gradle文件中添加依赖一样简单:

compile 'net.skoumal.fragmentback:fragment-back:0.1.0'

让你的片段实现BackFragment接口:

public abstract class MyFragment extends Fragment implements BackFragment {

    public boolean onBackPressed() {

        // -- your code --

        // return true if you want to consume back-pressed event
        return false;
    }

    public int getBackPriority() {
        return NORMAL_BACK_PRIORITY;
    }
}

通知你的片段关于背压:

public class MainActivity extends AppCompatActivity {

    @Override
    public void onBackPressed() {
        // first ask your fragments to handle back-pressed event
        if(!BackFragmentHelper.fireOnBackPressedEvent(this)) {
            // lets do the default back action if fragments don't consume it
            super.onBackPressed();
        }
    }
}

欲了解更多详细信息和其他用例,请访问GitHub页面:

https://github.com/skoumalcz/fragment-back

其他回答

在fragment类中,为back event放以下代码:

 rootView.setFocusableInTouchMode(true);
        rootView.requestFocus();
        rootView.setOnKeyListener( new OnKeyListener()
        {
            @Override
            public boolean onKey( View v, int keyCode, KeyEvent event )
            {
                if( keyCode == KeyEvent.KEYCODE_BACK )
                {
                    FragmentManager fragmentManager = getFragmentManager();
                    fragmentManager.beginTransaction()
                            .replace(R.id.frame_container, new Book_service_provider()).commit();

                    return true;
                }
                return false;
            }
        } );

 @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){

                    if (mDrawerLayout.isDrawerOpen(GravityCompat.START)){
                        mDrawerLayout.closeDrawer(GravityCompat.START);
                    }
                    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();

        }
}

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

对于那些谁使用静态片段

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

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();
    }
}