0

假設我在片段A,然後移動到B,然後使用後退按鈕返回到A. 在活動我執行以下控制裝置:OnBackPress片段中顯示未能更新

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

現在,該方法(如果有的話)將在一旦我們執行popBackStack()執行,? 如果沒有,我們如何能夠在按下後立即更改A的數據模型或UI組件(例如鍵盤或TextView)?它是否依賴於組件?

R.id.rl_content是容器。 請考慮兩種情況: 1.在R.id.rl和被替換 2.不R.id.rl並沒有被替換

回答

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,因爲在大多數情況下,這些解決方案將可能工作(考慮到f將是最後一次) ,但在某些(顯示/隱藏軟鍵盤,權限拒絕等)這些將無法正常工作,我們回到原點。 – lionheart

+0

非常有效的一點,我會假設你會用相同的邏輯來解決這個問題,以便自己克服這些問題,例如onfocuschange監聽器等等 – BIW

+0

我接受這個答案,因爲我確實在各種情況下使用了鏈接,尤其是(fm.getBackStackEntryCount()> 0)條件。 – lionheart

1

您可以通過幾種方式更改A的數據模型或UI組件。

案例1:當A是R.id.rl_content,並正在由B替換在這種情況下,你可以簡單地在片段A.

案例onCreateView更新所需的模型或UI 2:當A是不被替換。在這種情況下,片段A不知道何時更新其視圖。在你的活動的onBackpressed()中,如果Fragment 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(); 
       } 
      } 
     } 
    } 

而在你的片段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. 
} 
+0

+1,因爲在案例2中 - 我確實使用了接口,並且此解決方案可能在大多數情況下都能正常工作,而案例1是正確的。但是,在某些情況下(例如軟鍵盤,權限denail處理等),此解決方案(在大多數設備上)無法正常工作。我從來沒有寫過,但我確實提到過我已經嘗試使用onBackPressed。 – lionheart

+1

好吧所以我明白你想要處理依賴於單個碎片的情況。在這種情況下,您應該從個別片段中詢問他們是否想要處理後備事件。我已經在我的答案的編輯版本中解釋了這一點。 –

+0

它不起作用,可能會有'hackish'的做法。看起來有些事情會讓其他一些事情不起作用。這可能是特定的情況。我不確定。 – lionheart