2016-11-12 5 views
0

アクティビティがフラグメントを生成して後で再作成されると、そのフラグメントに関連付けられたビューは複製され、フラグメントが後で破棄されると破棄されます。Androidレクリエーションのビューはアクティビティレクリエーションで複製されます

これは、アクティビティがonSaveInstanceStateのオーバーライドで直接super.onSaveInstanceStateを呼び出す場合、または単純にコールバックをオーバーライドしない場合にのみ発生します。

再現する最小コード: MainActivity.java:

package com.example.trevor.test; 
import android.app.Activity; 
import android.os.Bundle; 
import android.util.Log; 
import android.widget.CheckBox; 
import android.widget.CompoundButton; 

/** 
* Created by trevor on 11/11/16. 
*/ 

public class MainActivity extends Activity { 
    MainFragment fragment = new MainFragment(); 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     CheckBox checkbox = (CheckBox)findViewById(R.id.checkBox); 
     checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
      @Override 
      public void onCheckedChanged(CompoundButton compoundButton, boolean b) { 
       if(b) 
       { 
        getFragmentManager().beginTransaction().add(R.id.container,fragment).commit(); 
       } 
       else 
       { 
        getFragmentManager().beginTransaction().remove(fragment).commit(); 
       } 
      } 
     }); 
    } 
} 

MainFragment.java:

package com.example.trevor.test; 

import android.app.Fragment; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

/** 
* Created by trevor on 11/11/16. 
*/ 

public class MainFragment extends Fragment { 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    { 
     return inflater.inflate(R.layout.fragment_main,container,false); 
    } 
} 

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <CheckBox 
     android:text="CheckBox" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id="@+id/checkBox" /> 

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

    </FrameLayout> 
</LinearLayout> 

がfragment_main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <TextView 
     android:text="Open" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id="@+id/textView" /> 
</LinearLayout> 

のAndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.trevor.test"> 

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
     <activity android:name=".MainActivity"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN"/> 
       <category android:name="android.intent.category.LAUNCHER"/> 
      </intent-filter> 
     </activity> 

    </application> 

</manifest> 

期待される動作:ボックスをチェックすると、単語 "オープン" は、以下の表示されるようになります。チェックを外すと、単語が消えます。

実際の動作:ボックスをチェックすると、下に「開く」という単語が表示されます。画面が回転すると、「開く」という単語が暗くなり、ボックスのチェックを外すと、その単語が通常の陰になります。

答えて

1

最初に追加しているFragmentは、Activityが再作成されると自動的に復元されます。それはFragmentの標準的な動作です。また、Activityレクリエーションの後にのチェック状態が復元されているため、そのonCheckedChanged()メソッドが再度起動し、Fragmentの別のインスタンスをロードしています。 CheckBoxをチェックしたままオリエンテーションを変更し続ける場合は、ますます多くのFragmentインスタンスが重なってしまいます。追加する前にFragmentインスタンスがすでに存在するかどうかを確認する必要があります。

あなたが最初にそれがFragmentManagerに添付だかどうかを確認する必要があり、それが見せているかどうかを判断したいとFragmentは、OnCheckedChangeListenerでそれを追加したり削除することは面倒なことになるだろう、自動的に再追加されようとしているので、 。インスタンス化されて追加されたことを確認した後、必要に応じてhide()show()という単なる単純な方が簡単でしょう。例えば

fragment = (MainFragment) getFragmentManager().findFragmentById(R.id.container); 

checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
    @Override 
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) { 
     if(b) 
     { 
      if(fragment == null) { 
       fragment = new MainFragment(); 
       getFragmentManager().beginTransaction().add(R.id.container, fragment).commit(); 
      } 
      else { 
       getFragmentManager().beginTransaction().show(fragment).commit(); 
      } 
     } 
     else 
     { 
      if (fragment != null) { 
       getFragmentManager().beginTransaction().hide(fragment).commit(); 
      } 
     } 
    } 
}); 

その後、MainFragmentの宣言から初期化を削除することができます。

MainFragment fragment; 
関連する問題