2016-04-12 36 views
2

私はナビゲーションドロワーを持っており、アイテムをクリックするとフルスクリーンの断片を表示/非表示/作成します。フラグメントが重複することがある - Android

ほとんどの場合、このコードはうまく機能します。しかし時々、たぶん1%の時間、私はアプリが既に実行されている間に開くときに狂ったフルスクリーンのフラグメントが重複して取得します。

私のコードに問題はありますか?それとも、認識できないAndroidの何か他に、既に作成されたタグの断片がありますか?ここで

は私が/非表示を表示する方法については、関連するコードです/フラグメントを作成します。

@SuppressWarnings("StatementWithEmptyBody") 
    @Override 
    public boolean onNavigationItemSelected(MenuItem item) { 

     // Get to drawer layout so we can interact with it 
     mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 

     // Get the fragment manager to remove/add fragments 
     FragmentManager fragmentManager = getSupportFragmentManager(); 

     // Handle navigation view item clicks here. 
     int id = item.getItemId(); 

     if (id == R.id.nav_profile) { 

      // Hide visible fragment 
      fragmentManager.beginTransaction().hide(getVisibleFragment()).commit(); 


      // Check if the fragment exists first. 
      if(fragmentManager.findFragmentByTag("profileFragment") != null) { 

       // If the fragment exists, show it (no reason to recreate it). 
       fragmentManager.beginTransaction() 
         .show(fragmentManager.findFragmentByTag("profileFragment")) 
         .commit(); 
      } else { 
       // If the fragment does not exist, add it to fragment manager with a tag to identify it. 

       // Create new fragment instance with required argument(s). 
       ProfileFragment fragment = ProfileFragment.newInstance(); 

       fragmentManager.beginTransaction() 
         .add(R.id.content_frame, fragment, "profileFragment") 
         .commit(); 
      } 

      // Set the title 
      mToolbarTitleTextView.setText(R.string.title_activity_profile); 

     } else if (id == R.id.nav_feed) { 

      // Hide visible fragment 
      fragmentManager.beginTransaction().hide(getVisibleFragment()).commit(); 


      // Check if the fragment exists first. 
      if(fragmentManager.findFragmentByTag("feedFragment") != null) { 
       // If the fragment exists, show it (no reason to recreate it). 
       fragmentManager.beginTransaction() 
         .show(fragmentManager.findFragmentByTag("feedFragment")) 
         .commit(); 
      } else { 
       // If the fragment does not exist, add it to fragment manager with a tag to identify it. 
       fragmentManager.beginTransaction() 
         .add(R.id.content_frame, new feedFragment(), "feedFragment") 
         .commit(); 
      } 

      // Set the title 
      mToolbarTitleTextView.setText(R.string.title_activity_feed); 

     } else if (id == R.id.nav_notifications) { 

      // Hide visible fragment 
      fragmentManager.beginTransaction().hide(getVisibleFragment()).commit(); 

      // Hide the post button 
      mPostButton.setVisibility(View.GONE); 

      // Check if the fragment exists first. 
      if(fragmentManager.findFragmentByTag("notificationsFragment") != null) { 
       // If the fragment exists, show it (no reason to recreate it). 
       fragmentManager.beginTransaction() 
         .show(fragmentManager.findFragmentByTag("notificationsFragment")) 
         .commit(); 
      } else { 
       // If the fragment does not exist, add it to fragment manager with a tag to identify it. 
       fragmentManager.beginTransaction() 
         .add(R.id.content_frame, new NotificationsFragment(), "notificationsFragment") 
         .commit(); 
      } 

      // Set the title 
      mToolbarTitleTextView.setText(R.string.title_activity_notifications); 

     } 

     mDrawerLayout.closeDrawer(GravityCompat.START); 
     return true; 
    } 

    // Useful method to hide the currently visible fragment 
    public Fragment getVisibleFragment(){ 
     FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager(); 
     List<Fragment> fragments = fragmentManager.getFragments(); 
     if(fragments != null){ 
      for(Fragment fragment : fragments){ 
       if(fragment != null && fragment.isVisible()) 
        return fragment; 
      } 
     } 
     return null; 
    } 

EDIT:デバッグにそれがハードになり、このエラーを再現するのはとても難しいです。それは無作為に起こったようです。

答えて

0

ここで私はこの問題を解決しました。

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

基本的に起こっていたことは、私は、画面上のフラグメント1+ていた場合、アプリがバックグラウンドであったAndroidシステムのリソースが低い実行した場合、であり、それをシャットダウンし、とき:私のMainActivityでは、私はこれをしませんでした復元された、MainActivity.onCreate()が呼び出されます、それがコール

super.onCreate(savedInstanceState); 

で再インスタンスすべてのフラグメントは、だから私はちょうどそれがnullで作られただろうし、これを再作成するすべてのそれらの断片から防ぐことができます。

重複している理由は、すべてが一度に表示されているためです。

これは正しい方法ではありませんが、私の問題は今すぐ解決します。P

1

なぜ非表示にして、メモリ内に一つだけの断片を維持し、fragmentManager.beginTransaction().replace()を使用して、必要に応じてフラグメントの状態を保存するために、フラグメントのライフサイクルメソッドを使用してフラグメントを隠すの面倒を避けることによって、このエラーを回避することができますfragmentManager.beginTransaction().add();ですべての断片を保ちます。

+0

以前は 'replace()'を使用していました。あなたは正しいです、私はライフサイクルメソッドを使用してフラグメント状態(もっと面倒)を保存することができます。これが記憶上の問題だと言っていますか? – Micro

+0

'FragmentTransaction.add()'を使うと、フラグメントのスタックを作成し、上にあるものだけを表示します(後で 'show()'や 'hide()'を使って変更します) 'FragmentTransaction。 replace() 'は、一度に1つのフラグメントしか保持しません。フラグメントの1つのインスタンスを一度にアクティブにするだけで、フラグメントの重複を避けることができます。 –

関連する問題