5

下部のナビゲーションタブで、その中のフラグメントを変更しているアクティビティがあります。これらのタブで前後にクリックすると、ある時点で機能しなくなります。私はそれにいくつかのログを入れてコードが正常に実行されます。しかし、断片は切り換えられていない。FragmentTransaction hide/showが動作しない場合があります

コードはkotlinであるが、それはかなりまっすぐ進む

fun showTabFragment(tag: String) { 
     val currentFragment: Fragment? = supportFragmentManager.fragments?.lastOrNull() 
     var fragment = supportFragmentManager.findFragmentByTag(tag) 
     val fragmentExists = fragment != null 
     if (fragment == null) { 
      when (tag) { 
       TAG_LOGBOOK -> fragment = LogbookFragment() 
       TAG_RECIPES -> fragment = RecipesFragment() 
       TAG_PROFILE -> fragment = ProfileFragment() 
       else -> fragment = MeetingPlacesFragment() 
      } 
     } 

     val transaction = supportFragmentManager.beginTransaction() 

     if (currentFragment != null) { 
      Log.i("jacek", "hiding " + currentFragment.javaClass.simpleName) 
      transaction.hide(currentFragment) 
     } 

     if (fragmentExists) { 
      Log.i("jacek", "showing " + fragment.javaClass.simpleName) 
      transaction.show(fragment) 
     } else { 
      Log.i("jacek", "adding " + fragment.javaClass.simpleName) 
      transaction.add(R.id.container, fragment, tag) 
     } 

     transaction.commit() 
    } 

フラグメントはかなり重いです。私はいくつかの軽量のもので試してみますが、それでも私の意見では問題ではありません。私が試すことができる他のものはありますか?私は、最新のサポートライブラリ使用してい

- ポイントは、それらを再作成することなく、クロスフェードアニメーションを追加することであるとしても25.2.0 私は断片を交換することに興味はないよ

+0

たぶん、あなたは呼んで問題があります同じトランザクション内の同じフラグメントに対して 'hide()'と 'show()'を実行しますか? 'currentFragment'が' fragment'と同じフラグメントを参照するときのように、これは確かにここで起こります。これについて言えば、 'supportFragmentManager.fragments'リスト内の最後のフラグメントは最後に表示されたフラグメント(最近追加されたフラグメント)になると主張するのは間違っていると思います。すべての 'フラグメント 'を反復して、' isVisible() 'が真であるものを検索するか、最後に表示されたフラグメントタグを保存し、後でそれを見つけなければなりません。 –

答えて

1

ここでの問題は、「でも、あなたかかわらず、です「現在の」フラグメントを隠していると、メモリにロードされている他のフラグメントがあり、不整合な動作をします。

これは、表示するフラグメント以外のすべてのフラグメントを隠すことで解決できます。

この回答に感謝します。 Show hide fragment in android

例:アリの答え@

private FragmentA fragmentA; 
private FragmentB fragmentB; 
private FragmentC fragmentC; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    fragmentA = FragmentA.newInstance(); 
    fragmentB = FragmentB.newInstance(); 
    fragmentC = FragmentC.newInstance(); 

} 

protected void displayFragmentA() { 

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
    if (fragmentA.isAdded()) { 
     ft.show(fragmentA); 
    } else { 
     ft.add(R.id.fragement_container, fragmentA); 
    } 

    if (fragmentB.isAdded()) { ft.hide(fragmentB); } 

    if (fragmentC.isAdded()) { ft.hide(fragmentC); } 

    ft.commit(); 
} 

同様に、あなたが(displayFragmentBするための機能を記述する必要があります)とdisplayFragmentC()

1

は良いですが、まだあなたは5つの断片を持っている場合を想像します。あなたがあなたの活動ののonCreate()メソッドでこれを行うことができます

// in BaseFragment 
    public abstract String getTAG(); 

    //in FragmentA, FragmentB and FragmentC 
    public String getTAG(){ 
     return TAG; 
    } 

    //Activity containing the fragments 
    //android.support.v4.app.Fragment;  
    private FragmentA fragmentA; //inherited BaseFragment 
    private FragmentB fragmentB; //inherited BaseFragment 
    private FragmentC fragmentC; //inherited BaseFragment 
    private ConcurrentHashMap<String,BaseFragment> mapOfAddedFragments = new ConcurrentHashMap<>(); 


    /** 
    * Displays fragment A 
    */ 
    private void displayFragmentA() { 
     displayFragment(fragmentA) 
    } 

    /** 
    * Displays fragment B 
    */ 
    private void displayFragmentB() { 
     displayFragment(fragmentB) 
    } 

    /** 
    * Displays fragment C 
    */ 
    private void displayFragmentC() { 
     displayFragment(fragmentC) 
    } 


    /** 
    * Loads a fragment using show a fragment 
    * @param fragment 
    */ 
    private void displayFragment(BaseFragment fragment){ 
     if(!mapOfAddedFragments.containsKey(fragment.getTAG())) 
      mapOfAddedFragments.put(fragment.getTAG(), fragment); 

     showFragment(fragment.getTAG(), R.id.containerBody); 
    } 

    /** 
    * Displays a fragment and hides all the other ones 
    * @param fragmentTag is the tag of the fragment we want to display 
    */ 
    private void showFragment(String fragmentTag, @IdRes int containerViewId){ 
     FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction(); 
     BaseFragment fragment = null; 

     fragment = mapOfAddedFragments.get(fragmentTag); 
     if(fragment != null) { 
      if (fragment.isAdded()) 
       ft.show(fragment); 
      else { //fragment needs to be added to the frame container 
       ft.add(containerViewId, fragment, fragment.getTAG()); 
      } 
     } 
     else //the chosen fragment doesn't exist 
      return; 

     //we hide the other fragments 
     for (ConcurrentHashMap.Entry<String, BaseFragment> entry : mapOfAddedFragments.entrySet()){ 
      if(!entry.getKey().equals(fragmentTag)){ 
       BaseFragment fragmentTemp = entry.getValue(); 
       // Hide the other fragments 
       if(fragmentTemp != null) 
        if(fragmentTemp.isAdded()) 
         ft.hide(fragmentTemp); 
      } 
     } 

     //commit changes 
     ft.commit(); 
    } 

し、それらをインスタンス化する:これはあなたの破片を表示/非表示する別の方法です

//don't forget to get the .TAG elsewhere before using them here 
    //never call them directly 
    private void instantiateFragments(Bundle inState) { 
     if (inState != null) { 
      fragmentA = inState.containsKey(FragmentA.TAG) ? 
        (FragmentA) getSupportFragmentManager().getFragment(inState, FragmentA.TAG): 
        FragmentA.newInstance(FragmentA.TAG,"0"); 

      fragmentB = inState.containsKey(FragmentB.TAG) ? 
        (FragmentB) getSupportFragmentManager().getFragment(inState, FragmentB.TAG): 
        FragmentB.newInstance(FragmentB.TAG,"1");   

      fragmentc = inState.containsKey(FragmentC.TAG) ? 
        (FragmentC) getSupportFragmentManager().getFragment(inState, FragmentC.TAG): 
        FragmentC.newInstance(FragmentC.TAG,"2");   
     } 
     else{ 
      fragmentA = FragmentA.newInstance(FragmentA.TAG,"0"); 
      fragmentB = FragmentB.newInstance(FragmentB.TAG,"1"); 
      fragmentc = FragmentC.newInstance(FragmentC.TAG,"2"); 
     } 
    } 
関連する問題