2016-06-14 5 views
0

샘플에서 조각 용으로 commitAllowingStateLoss()commit() 메서드의 차이점을 배우려고합니다. 이제는 IllegalArgumentException이 액티비티 저장 인스턴스 후에 commit()을 사용하는 경우 나타납니다 (예 : 활동이 백그라운드에서 실행될 때 commit() 실행).액티비티가 다시 생성 된 후 조각이 겹칩니다.

그러나 또 다른 문제가 나타나고 조각이 겹칩니다. 나는 왜 그런지 모르고 문제를 해결할 수 없다.

내 코드는 다음과 같습니다.

FragmentMainActivity에는 조각 전환을위한 두 개의 단추가 있습니다.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical"> 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal"> 

    <Button 
     android:id="@+id/btn_fragment1" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" 
     android:text="fragment 1" /> 

    <Button 
     android:id="@+id/btn_fragment2" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" 
     android:text="fragment 2" /> 
</LinearLayout> 

<FrameLayout 
    android:id="@+id/root" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#ffffffff"></FrameLayout> 

ID "루트"와 FrameLayout이

은 단편에 대한 컨테이너이다.

public class FragmentMainActivity extends AppCompatActivity implements View.OnClickListener { 

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

    findViewById(R.id.btn_fragment1).setOnClickListener(this); 
    findViewById(R.id.btn_fragment2).setOnClickListener(this); 
} 

PlusOneFragment plusOneFragment; 
PlusTwoFragment plusTwoFragment; 

@Override 
public void onClick(View v) { 
    int i = v.getId(); 
    if (i == R.id.btn_fragment1) { 
     findViewById(R.id.root).postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
       if (getSupportFragmentManager().findFragmentByTag("tag1") == null) { 
        plusOneFragment = PlusOneFragment.newInstance("1", "2"); 
        transaction.add(R.id.root, plusOneFragment, "tag1"); 
       } else { 
        plusOneFragment = (PlusOneFragment) getSupportFragmentManager().findFragmentByTag("tag1"); 
       } 
       if (getSupportFragmentManager().findFragmentByTag("tag2") != null) { 
        plusTwoFragment = (PlusTwoFragment) getSupportFragmentManager().findFragmentByTag("tag2"); 
        transaction.hide(plusTwoFragment); 
       } 
       transaction.show(plusOneFragment).commitAllowingStateLoss(); 
      } 
     }, 3000); 
    } else if (i == R.id.btn_fragment2) { 
     findViewById(R.id.root).postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
       if (getSupportFragmentManager().findFragmentByTag("tag2") == null) { 
        plusTwoFragment = PlusTwoFragment.newInstance("1", "2"); 
        transaction.add(R.id.root, plusTwoFragment, "tag2"); 
       } else { 
        plusTwoFragment = (PlusTwoFragment) getSupportFragmentManager().findFragmentByTag("tag2"); 
       } 
       if (getSupportFragmentManager().findFragmentByTag("tag1") != null) { 
        plusOneFragment = (PlusOneFragment) getSupportFragmentManager().findFragmentByTag("tag1"); 
        transaction.hide(plusOneFragment); 
       } 
       transaction.show(plusTwoFragment).commitAllowingStateLoss(); 
      } 
     }, 3000); 
    } 
} 
} 

첫 번째로 fragment1을 표시하려면 button1을 클릭하고 fragment2를 표시하려면 button2를 클릭하십시오. 정상적으로 작동합니다. 이러한 작업이 끝나면 button1을 다시 클릭 한 다음 집을 클릭하면 앱이 백그라운드에서 실행됩니다. 시뮬레이션 된 낮은 memorey 장면에, 나는 그 때 과정을 죽인다. 모든 작업은 3 초에 일어났습니다.

마지막으로, 최근 기록 (활동 재현)에서 앱을 열었을 때 두 부분이 서로 겹치는 것을 발견했습니다. 이 문제는 어떻게 처리됩니까? (프로세스가 포어 그라운드 일 때 문제가 발생하지 않는 이유는 무엇입니까?) 그리고이 문제로 무엇을 할 수 있습니까? 조각으로

overlapping fragments

+0

은 - 다시 조각은 내가으로이 추가 해요 –

+0

도움이 있으면 알려 대신 add.Let의 방법을 제거하려고 removed.Also 아닌 조각 배경 색상 (흰색 말을)주고 확인하는 사용 대답하십시오. 동의하십시오. –

+0

예, 백 그라운드 색상을 추가하면 도움이됩니다. 그러나 나는 이것이 왜 일어나는 지 모른다. 프로세스가 종료되지 않으면 백그라운드 색상없이 제대로 작동합니다. – Jone

답변

0

도움이 될 희망을 문제

Fragment fragment = (Fragment) YourClass.newInstance(); 

    FragmentManager fragmentManager = getSupportFragmentManager(); 
        fragmentManager.popBackStack(); 
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 

        fragmentTransaction.replace(R.id.flContent, fragment); 
        //TODO Add to backstack 


        fragmentTransaction.addToBackStack(null); 

        fragmentTransaction.commit(); 

를 해결할 수 있습니다 사용 android:background="@android:color/white" (흰색 말을) 다시 확인합니다.

fragmentTransaction.replace("containerId", fragment); 

이 수동으로 당신의 조각을 제거 할 수 있습니다 layout.You의 이전 조각을 대체으로 -을 : 당신의 조각을 제거하고 대신 add.For 전직의 방법을 대체하려고 another.Also 이상을 추가되지 않습니다 beacuse 입니다 잘

Fragment fragment = getSupportFragmentManager().findFragmentByTag(TAG_FRAGMENT); 
if(fragment != null) 
    getSupportFragmentManager().beginTransaction().remove(fragment).commit(); 
+0

예, 두 방법 모두 잘 작동합니다. 프로세스가 포어 그라운드 일 때 문제가 발생하지 않은 이유를 설명해 주시겠습니까? 감사. – Jone

+0

@Jone 이것은 귀하의 활동이 재 작성되고 귀하의 단편과 b가 파괴되지 않고 새로운 주 대신 이전 상태에서 재개되기 때문일 수 있습니다. http://stackoverflow.com/questions/18590582/overlapping-fragments-when- 재개 활동 및 http : // stackoverflow.co.kr/questions/15074320/fragment-overlaps-on-activity-rotation –

+0

좋아요, 고마워요. – Jone

0

는 두 번째 열 때 가기 backstack에서 첫번째 조각을 제거 할 필요가 가기 backstack에 남아 있습니다. popBackStack 내가이 루트 요소에게 당신의 조각을 배경 색상을 지정하면

+0

예, 도움이됩니다. 감사. 하지만 replace() 메소드는 조각을 파괴합니다. 그래서 show()와 hide() 메소드를 사용해야합니다. – Jone

관련 문제