10

私のアプリで "standart"フラグメントナビゲーションを実装する必要があります(linkを参照してください)。方向のフラグメント復元状態が変更されました

デバイスがポートレートモードの場合、1つのフラグメントしか表示されず、ランドスケープモードに切り替えると2つのフラグメントが表示されます。

1)私は別の肖像画や風景のレイアウトを持つ唯一の1アクティビティを使用します。

は、私は、この2種類の方法を実行しようとしました。

ポートレートレイアウトXML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <FrameLayout 
     android:id="@+id/main_frame_fragment_container" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 

</RelativeLayout> 

そしてhere`sランドスケープレイアウト:

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

    <FrameLayout 
     android:id="@+id/main_frame_fragment_container_left" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_weight="1" /> 

    <FrameLayout 
     android:id="@+id/main_frame_fragment_container_right" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_weight="1" /> 

</LinearLayout> 

Activity`s のonCreate方法:

private static ItemsFragment mItemsFragment; 
    private static ItemDetailsFragment mItemDetailsFragment; 

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

     if (mItemsFragment == null) { 
      mItemsFragment = ItemsFragment.newInstance(); 
     } 
     if (mItemDetailsFragment == null) { 
      mItemDetailsFragment = ItemDetailsFragment.newInstance(); 
     } 

     if (isLandscape()) { 
      getSupportFragmentManager().beginTransaction().replace(R.id.main_frame_fragment_container_left, mItemsFragment) 
        .commit(); 
      getSupportFragmentManager().beginTransaction() 
        .replace(R.id.main_frame_fragment_container_right, mItemDetailsFragment).commit(); 
     } else { 
      getSupportFragmentManager().beginTransaction().replace(R.id.main_frame_fragment_container, mItemsFragment) 
        .commit(); 
     } 
    } 

そしてthat`s私は2番目の断片をリフレッシュする:

Bundle bundle = new Bundle(); 
bundle.putSerializable(BaseFragment.KEY_BUNDLE_ITEM, response.getItem()); 
mItemDetailsFragment = ItemDetailsFragment.newInstance(bundle); 
if (isLandscape()) { 
    getSupportFragmentManager().beginTransaction() 
          .replace(R.id.main_frame_fragment_container_right, mItemDetailsFragment).commit(); 
} else { 
    getSupportFragmentManager().beginTransaction() 
          .replace(R.id.main_frame_fragment_container, mItemDetailsFragment).addToBackStack(null).commit(); 
} 

また、フラグメントの状態を保存して復元するため、ローテーション後にデータが消えない。私の場合、一般的にこのコードは適切に動作します。

2)アクティビティポートレートモードとランドスケープモードでは、2つのアクティビティと同じレイアウトを使用します。

のxmlレイアウトは、景観のために前のものと同じです:

<FrameLayout 
     android:id="@+id/main_frame_fragment_container_left" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_weight="1" /> 

    <FrameLayout 
     android:id="@+id/main_frame_fragment_container_right" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_weight="1" /> 

</LinearLayout> 

のonCreate方法(それが第一の場合にあったように断片の実体は、静的ではないことに注意してください): プライベートItemsFragment mItemsFragment; プライベートItemDetailsFragment mItemDetailsFragment;

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

    if (savedInstanceState == null) { 
     mItemsFragment = ItemsFragment.newInstance(); 
     mItemDetailsFragment = ItemDetailsFragment.newInstance(); 

     getSupportFragmentManager().beginTransaction().replace(R.id.main_frame_fragment_container_left, mItemsFragment) 
     .commit(); 
     getSupportFragmentManager().beginTransaction() 
     .replace(R.id.main_frame_fragment_container_right, mItemDetailsFragment).commit(); 
    } 
} 

、デバイスがポートレートモードであれば、今、私は新しい活動を開始します。

if (isLandscape()) { 
    Bundle bundle = new Bundle(); 
    bundle.putSerializable(BaseFragment.KEY_BUNDLE_ITEM, response.getItem()); 
    mItemDetailsFragment = ItemDetailsFragment.newInstance(bundle); 
    getSupportFragmentManager().beginTransaction() 
     .replace(R.id.main_frame_fragment_container_right, mItemDetailsFragment).commit(); 
} else { 
    Intent intent = new Intent(getApplicationContext(), DetailsActivity.class); 
    intent.putExtra(KEY_ITEM, response.getItem()); 
    startActivity(intent); 
} 

そして、最後に、第二Activity`s のonCreate方法で:

protected void onCreate(Bundle arg0) { 
    super.onCreate(arg0); 
    setContentView(R.layout.activity_details); 

    if (isLandscape()) { 
     finish(); 
    } 

    Item item = (Item) getIntent().getExtras().getSerializable(KEY_ITEM); 

    Bundle bundle = new Bundle(); 
    bundle.putSerializable(BaseFragment.KEY_BUNDLE_ITEM, item); 

    ItemDetailsFragment mItemDetailsFragment = ItemDetailsFragment.newInstance(bundle); 

    getSupportFragmentManager().beginTransaction() 
     .replace(R.id.main_frame_fragment_container, mItemDetailsFragment).commit(); 
} 

デバイスがランドスケープモードに回転すると、2番目のアクティビティが終了し、2番目のアクティビティが2つのフラグメントで表示されます(期待どおり)。

質問:私は肖像画や風景モードで第二のフラグメントの状態を変更する場合は、このの私は気にしないので、静的変数は、と(同じフラグメントが使用されている)の断片を保存する第一の場合

。しかし、私はそれを静的フィールドとして保存することをお勧めしません。

2番目のケースでは、アクティビティAフラグメントB(ランドスケープ)とアクティビティBフラグメントB(ポートレート)を同期する方法がわかりません。フラグメント(何らかのボタンを切り替えるなど)を変更してデバイスを回転させると、変更が別のフラグメントに適用されるはずです。

どのような場合が一般的ですか、2番目の場合、どのように同期の問題を解決できますか?もっと簡単な方法があるかもしれません。読んでくれてありがとう、私はあなたが私を助けることを願っています:)

答えて

2

ちょうどこのメイトhttp://developer.android.com/guide/components/fragments.htmlに従ってください。断片を静的にしてはいけません(ちょうどうんざりしています)

+0

ありがとう、これが私の必要です。私は昨日この記事で私を混乱させましたが、正確に何を覚えていないのです。 – UneXp

+2

奇妙なだけでなく、メモリリークもあります。 – mwieczorek

+0

変なことで奇妙なクラッシュが発生する - >メモリリーク:0 –

関連する問題