OnBackPress要显示的片段无法更新

时间:2016-12-07 13:08:50

标签: android android-fragments android-activity fragment-backstack

假设我在片段A中,然后移动到B,然后使用“返回”按钮返回到A. 在活动中,我正在执行以下覆盖:

Text.Encoding.decodeUtf8

并且在显示B的时候是这样的:

@Override
public void onBackPressed(){
    FragmentManager fm = getSupportFragmentManager();
    Fragment frag = fm.findFragmentByTag(Consts.A);
    if (frag != null){
        Log.d(Consts.TAGS.ACTIVITY_ORDER,"");
        fm.beginTransaction().remove(frag).commit();
        fm.popBackStack();
    }
}

现在,一旦我们执行 FragmentManager fm = getActivity().getSupportFragmentManager(); Fragment f = BFragment.newInstance(Consts.B); fm.beginTransaction() .replace(R.id.rl_content, f, Consts.B) .addToBackStack(null) .commit(); ,哪个方法(如果有的话)将在A中执行? 如果没有,我怎样才能在后退后更改A的数据模型或UI组件(例如键盘或popBackStack())?它是否依赖于组件?

TextView是容器。 请考虑2个案例: 1. A在R.id.rl_content并被替换 2. A不在R.id.rl且未被替换

2 个答案:

答案 0 :(得分:1)

如果你总是从片段B回到片段A,反之亦然,我会在片段中推荐这个解决方案。

@Override
    public void onResume() {
        super.onResume();

        Fragment f = AFragment.newInstance(Consts.A);

        if(getView() == null){
            return;
        }
        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){
                    FragmentTransaction trans = getFragmentManager().beginTransaction();
                    trans.replace(R.id.rl_content, f);
                    trans.addToBackStack(null);
                    trans.commit();
                    return true;
                }
                return false;
            }
        });
    }

您可以使用相同的代码自由地从B移动到A和A到B.如果你想要一个更有活力的方法,例如你想从片段A到片段C,或片段B到片段C,然后当你按回去时回到堆栈上的前一个片段。我的目标是使用Kyle Falconer's Solution here

如果链接死亡,我将在此处发布代码:

@Override
public void onBackPressed(){
    FragmentManager fm = getFragmentManager();
    if (fm.getBackStackEntryCount() > 0) {
        Log.i("MainActivity", "popping backstack");
        fm.popBackStack();
    } else {
        Log.i("MainActivity", "nothing on backstack, calling super");
        super.onBackPressed();  
    }
}

我还没有测试过第二个解决方案,但是使用第一个解决方案。

答案 1 :(得分:1)

您可以通过几种方式更改A的数据模型或UI组件。

案例1:当A在R.id.rl_content中并被B替换时。在这种情况下,您只需更新片段A的onCreateView中所需的模型或UI。

案例2:当A未被替换时。在这种情况下,片段A不知道何时更新其视图。在活动的onBackpressed()中,如果弹出片段B,则可以调用Fragment A的updateView()方法。

@Override 
public void onBackPressed(){ 
    FragmentManager fm = getSupportFragmentManager(); 
    FragmentB fragmentB = (FragmentB)fm.findFragmentByTag(Consts.B); 
    if (fragmentB != null){ 
        Log.d(Consts.TAGS.ACTIVITY_ORDER,"");
        fm.beginTransaction().remove(fragmentB).commit(); 
        fm.popBackStack(); 
        FragmentA fragmentA = (FragmentA)fm.findFragmentByTag(Consts.A);
        if (fragmentA != null) {
             fragmentA.updateView();
        }
    } 
} 

修改

据我所知,您还想处理隐藏键盘等情况。 为此,您可能希望将backpress事件传递给各个片段。有点像这样:

@Override 
public void onBackPressed(){ 
    FragmentManager fm = getSupportFragmentManager(); 
    FragmentB fragmentB = (FragmentB)fm.findFragmentByTag(Consts.B); 
    if (fragmentB != null){ 
            if (!fragmentB.onBackPress()) {
                 // This means fragment B doesn't want to consume backpress therefore remove it.
                 Log.d(Consts.TAGS.ACTIVITY_ORDER,"");
                 fm.beginTransaction().remove(fragmentB).commit(); 
                 fm.popBackStack(); 
                 FragmentA fragmentA = (FragmentA)fm.findFragmentByTag(Consts.A);
                 if (fragmentA != null) {
                     fragmentA.updateView();
                 }
            }
        } 
    } 

在你的Fragment B中创建一个onBackPress函数,如下所示:

public boolean onBackPressed() {
  // if keyboard is showing then hide it here and return true to consume the back press event or else return false to dismiss this fragment. 
}