2017-02-24 6 views
0

オリエンテーションの変更に関するフラグメントの状態を維持しているAndroidの迷惑なタスクにアクセスしました。オリエンテーションの変更に関する複数のフラグメント

まず最初に、私はStackOverフローですべてのソリューションを試してみましたが、私は尋ねなかった良い結果しか持っていませんでした。

オリエンテーションの変更でフラグメントの変更を維持できましたが、ユーザーがフラグメントを切り替えたときにフラグメントの状態を保存できませんでした。このため、このソリューションを削除して新しいものを探しました。

私のアイデアは、断片を少しだけ隠してもう見えなくても、断片をもう一度作り直すことがないので、フラグメントを全体的に置き換える必要はなく、表示/非表示することです。

less talk、more Code。

int mID = (int) drawerItem.getIdentifier(); 

         String mTag = ""; 
         switch (mID){ 
          case 0: 
           mTag = "ViewPager"; 
           break; 
          case 1: 
           mTag = "Browser"; 
           break; 
          case 2: 
           mTag = "Settings"; 
           break; 
         } 

         if (savedInstanceState == null) { 
          ShowHideFrags(mID); 
         } else { 
          switch (mID){ 
           case 0: 
            Log.i("ASDSADSA","4"); 
            mViewPager = (ViewPagerFragment) getSupportFragmentManager().findFragmentByTag(mTag); 
            ShowHideFrags(mID); 
            break; 
           case 1: 
            Log.i("ASDSADSA","5"); 
            mWebFrag = (WVFragment) getSupportFragmentManager().findFragmentByTag(mTag); 
            ShowHideFrags(mID); 
            break; 
           case 2: 
            Log.i("ASDSADSA","6"); 
            mSettings = (SettingsFragment) getSupportFragmentManager().findFragmentByTag(mTag); 
            ShowHideFrags(mID); 
            break; 
          } 
         } 

このコードは、私がMikepenzによって「材質引き出し」ライブラリを使用しています、ナビゲーション引き出しにクリックを処理します。

コードが示すように、私はViewPager,Browser、およびSettingsの3つのフラグメントを持っています。

ここで私の問題は、オリエンテーションとgetFragmentメソッドなしで再作成され、コードに問題はありませんが、この変更のサポートを追加すると、フラグメントが再び再作成されます。私はすでにコードを変更し、変更を記録し、何が間違っているかを何度も試してみました。

最初の起動時にShowHideFrags(int x)メソッドが呼び出され、elseに進みます。

ShowHideFrags(int型x)はのコード:

private void ShowHideFrags(int SelectedFrag){ 
    if(mFragmentManager == null) 
     mFragmentManager = getSupportFragmentManager(); 

    android.support.v4.app.FragmentTransaction ft = mFragmentManager.beginTransaction(); 
    switch (SelectedFrag){ 
     case 0: 
      if(mViewPager == null) 
       mViewPager = new ViewPagerFragment(); 

      if(!mViewPager.isAdded()) 
       ft.add(R.id.fragment,mViewPager,"Viewpager"); 

      if(!mViewPager.isVisible()){ 
       if((mSettings != null && mSettings.isVisible())) 
        ft.hide(mSettings); 

       if((mWebFrag != null && mWebFrag.isVisible())) 
        ft.hide(mWebFrag); 

       ft.show(mViewPager); 
      } else { 
       if((mSettings != null && mSettings.isVisible())) 
        ft.hide(mSettings); 

       if((mWebFrag != null && mWebFrag.isVisible())) 
        ft.hide(mWebFrag); 
      } 

      ft.commit(); 
      break; 
     case 1: 
      if(mWebFrag == null) 
       mWebFrag = new WVFragment(); 


      if(!mWebFrag.isAdded()) 
       ft.add(R.id.fragment,mWebFrag,"Browser"); 

      if(!mWebFrag.isVisible()) { 
       if((mSettings != null && mSettings.isVisible())) 
        ft.hide(mSettings); 

       if(mViewPager != null && mViewPager.isVisible()) 
        ft.hide(mViewPager); 

       ft.show(mWebFrag); 

      } else { 
       if((mSettings != null && mSettings.isVisible())) 
        ft.hide(mSettings); 

       if((mViewPager != null && mViewPager.isVisible())) 
        ft.hide(mViewPager); 
      } 
      ft.commit(); 
      break; 
     case 2: 
      if(mSettings == null) 
       mSettings = new SettingsFragment(); 

      if(!mSettings.isAdded()) 
       ft.add(R.id.fragment,mSettings,"Settings"); 

      if(!mSettings.isVisible()) { 
       if((mViewPager != null && mViewPager.isVisible())) 
        ft.hide(mViewPager); 

       if((mWebFrag != null && mWebFrag.isVisible())) 
        ft.hide(mWebFrag); 

       ft.show(mSettings); 
      } else { 
       if((mViewPager != null && mViewPager.isVisible())) 
        ft.hide(mViewPager); 

       if((mWebFrag != null && mWebFrag.isVisible())) 
        ft.hide(mWebFrag); 
      } 
      ft.commit(); 
      break; 
    } 
} 

マイonSaveInstanceStateのコード:その後、ソリューションをしようとして4日後、私は座って、素敵な飲み物を持っていたので、

@Override 
protected void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 

    try{ 
     long mSelectedItem = result.getCurrentSelection(); 
     android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager(); 
     android.support.v4.app.Fragment currentFragment = fragmentManager.findFragmentById(R.id.fragment); 
     getSupportFragmentManager().putFragment(outState,currentFragment.getTag(),currentFragment); 
     outState.putLong("SelectedItem",mSelectedItem); 
    } catch (Exception e){ 
     e.printStackTrace(); 
    } 


} 

答えて

0

、Iこの厄介な問題を解決する方法を考え出しました。

私は進行状況や手順を説明するのがすごく面白くないので、私はまっすぐになり、プロの回答者のようになるように最善を尽くします。

まず最初に、私のアプリにはナビゲーション・ドロワーがあり、再作成せずにフラグメントを表示/非表示したいのですが、時間をかけずにそのようなミッションを達成するのはちょっと難しい作業でした。ライフサイクルを理解し、何が起こるのかを知るために、あらゆるステップにログを追加して、何が起こっているのかを知っています。

アプリが起動し、フラグメント.show().hide()だけを切り替えると、バンドルはnullになります。したがって、

if (savedInstanceState == null) { 
    LogMessage("Bundle Is Null, normal stuff"); 
    ShowHideFrags(mID); 
} 

使用方法ShowHideFragsは、そのタスクは断片のみがnullかそうでないかどうかを確認し、それがnullだ場合、選択、および選択された1つを示していない人たちを非表示にすることで、最後に添付されますメソッドは新しいフラグメントを作成して追加します。

最初のことは簡単です。向きが変わると、バンドルはnullにならず、保存されたフラグメントがあります。まずバンドルに保存する必要があります。

@Override 
protected void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    long mSelectedItem = result.getCurrentSelection(); 

    try{ 
     FragmentManager mFM = getSupportFragmentManager(); 
     Fragment currentFragment = null; 


     switch (mTag){ 
      case "ViewPager": 
       currentFragment = mViewPager; 
       break; 
      case "Browser": 
       currentFragment = mWebFrag; 
       break; 
      case "Settings": 
       currentFragment = mSettings; 
       break; 
     } 

     mFM.putFragment(outState,mTag,currentFragment); 
     LogMessage(String.format("The following fragment '%1$s' with position %2$s was saved",mTag,String.valueOf(mSelectedItem))); 
    } catch (Exception e){ 
     e.printStackTrace(); 
    } 
    outState.putLong("SelectedItem",mSelectedItem); 
} 

ハードコーディングされた文字列を変数として使用せずに使用する理由は何ですか?私は怠け者だから。重要な注意点は、現在のフラグメントをfindFragmentByTagメソッドで保存しないでください。選択されたフラグメントではなく、最後に適用されたフラグメントが表示されるため、選択されているフラグメントの種類を手動で確認する必要があります。

断片を言及忘れないように、私はコード

private ViewPagerFragment mViewPager; 
private WVFragment mWebFrag; 
private SettingsFragment mSettings; 

mTagの先頭にこれらの次の断片を持っているナビゲーションの引き出しでonClickメソッドの内部で、私が追加mTag価値を持っている、フラグメント・タグであります、次のコードで:

switch (mID) { 
    case 0: 
    mTag = "Viewpager"; 
    break; 

    case 1: 
    mTag = "Browser"; 
    break; 

    case 2: 
    mTag = "Settings"; 
    break; 
} 

今、私たちはMTAGがバンドルがnullのチェックが行われたときに、割り当てられ、保存部分も行われているバンドルしている、今、私たちは、バンドルがnullでないとき一部を行う必要があります。

最初のコードは、次に、について説明

if(getSupportFragmentManager().findFragmentByTag(mTag) != null){ 
             LogMessage(String.format("Fragment with tag '%1$s' was found",mTag)); 
             mViewPager = (ViewPagerFragment) getSupportFragmentManager().findFragmentByTag(mTag); 
             if(!mViewPager.isVisible()) { 
              LogMessage("Not Visible"); 
              ShowHideFrags(mID); 
             } else { 
              LogMessage("Visible"); 
             } 
            } else { 
             LogMessage(String.format("Fragment with tag '%1$s' was NOT found", mTag)); 

              if(!ReturnCurrentFragment().equalsIgnoreCase(mTag)){ 
              LogMessage("Not the Same"); 
              ShowHideFrags(mID); 
             } else { 
              LogMessage("It's the Same"); 
             } 
            } 

private Fragment ReturnCurrentFragment(){ 
    return getSupportFragmentManager().findFragmentById(R.id.fragment); 
} 

上記のコードは、バンドルがnullでない場合、else節内にあります。最初に、選択したフラグメント(バンドルに保存されている)が実際にロード可能であるかどうかを確認し、割り当てられている場合は割り当て、そうでない場合は他のフラグメントが表示されることを確認します。ShowHideFragsを呼び出します。

フラグメントが表示されているときは、何もしません。さらにバンドル内にないかどうかチェックし、バンドルされていない場合は再読み込みができるかどうかを確認しますので、* 1を2回再作成しません。

このコードでは、私はほとんどすべての迷惑なバグが発生する可能性があります世話をしました希望

ShowHideFrags(int x)のコード:

private void ShowHideFrags(int SelectedFrag){ 
    if(mFragmentManager == null) 
     mFragmentManager = getSupportFragmentManager(); 

    android.support.v4.app.FragmentTransaction ft = mFragmentManager.beginTransaction(); 
    switch (SelectedFrag){ 
     case 0: 
      if(mViewPager == null) 
       mViewPager = new ViewPagerFragment(); 

      if(!mViewPager.isAdded()) 
       ft.add(R.id.fragment,mViewPager,"Viewpager"); 

      if(!mViewPager.isVisible()){ 
       if((mSettings != null && mSettings.isVisible())) 
        ft.hide(mSettings); 

       if((mWebFrag != null && mWebFrag.isVisible())) 
        ft.hide(mWebFrag); 

       ft.show(mViewPager); 
      } else { 
       if((mSettings != null && mSettings.isVisible())) 
        ft.hide(mSettings); 

       if((mWebFrag != null && mWebFrag.isVisible())) 
        ft.hide(mWebFrag); 
      } 

      ft.commit(); 
      break; 
     case 1: 
      if(mWebFrag == null) 
       mWebFrag = new WVFragment(); 


      if(!mWebFrag.isAdded()) 
       ft.add(R.id.fragment,mWebFrag,"Browser"); 

      if(!mWebFrag.isVisible()) { 
       if((mSettings != null && mSettings.isVisible())) 
        ft.hide(mSettings); 

       if(mViewPager != null && mViewPager.isVisible()) 
        ft.hide(mViewPager); 

       ft.show(mWebFrag); 

      } else { 
       if((mSettings != null && mSettings.isVisible())) 
        ft.hide(mSettings); 

       if((mViewPager != null && mViewPager.isVisible())) 
        ft.hide(mViewPager); 
      } 
      ft.commit(); 
      break; 
     case 2: 
      if(mSettings == null) 
       mSettings = new SettingsFragment(); 

      if(!mSettings.isAdded()) 
       ft.add(R.id.fragment,mSettings,"Settings"); 

      if(!mSettings.isVisible()) { 
       if((mViewPager != null && mViewPager.isVisible())) 
        ft.hide(mViewPager); 

       if((mWebFrag != null && mWebFrag.isVisible())) 
        ft.hide(mWebFrag); 

       ft.show(mSettings); 
      } else { 
       if((mViewPager != null && mViewPager.isVisible())) 
        ft.hide(mViewPager); 

       if((mWebFrag != null && mWebFrag.isVisible())) 
        ft.hide(mWebFrag); 
      } 
      ft.commit(); 
      break; 
    } 
} 

* 1:フラグメントがない場合のは、例えばそのコードブロックを削除してみましょう、とそのブロックがあまりにもではなく、あなたが切り替えよう、選択しましたフラグメントが前のフラグメントにオーバーレイするか、またはブランクフラグメントが表示される可能性があるため、現在のフラグメントと等しい場合はShowHideFragsにそのフラグメントを表示する必要があります。したがって、再びフラグメントを再作成せず、お互い。

この回答がお役に立てば、お気軽にお答えください。

関連する問題