5

아래쪽 탐색 탭에서 조각을 변경하는 활동이 있습니다. 해당 탭에서 앞뒤로 클릭하면 어떤 시점에서 작동이 멈 춥니 다. 일부 로그를 넣으면 코드가 제대로 실행됩니다. 그러나 파편들은 바뀌지 않고있다.FragmentTransaction 숨기기/표시가 때때로 작동하지 않습니다

코드 코 틀린에 있지만 오히려 똑바로 앞으로

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

어쩌면 당신이 호출 할 때 문제가있는 것입니다 :) (활동의 방법을

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

을 그리고 당신은에서 onCreate에서이 작업을 수행 할 수 있습니다를 인스턴스화 : 이것은 당신의 조각 숨기기/표시하는 또 다른 방법입니다 동일한 트랜잭션 내에서 동일한 조각에 대해'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 개 조각이있는 경우 상상에 대한 함수를 작성해야합니다.

//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"); 
     } 
    }