プログラムで(動的に)追加されたFragment
sの使用方法(または「使用可能」)getChildFragmentManager()
これが私の例です。
MainActivity
が1つ、OuterFrag
が1つ、InnerFrag
が1つあります。 OuterFrag
によってMainActivity
をFragmentManager
に動的に追加します。また、InnerFrag
を動的にOuterFrag
に追加することも、FragmentManager
によって動的に行います。しかし、InnerFrag
を置き換えないで、OuterFrag
の子としてOuterFrag
を正確に追加し、MainActivity
の新しい子にしたいと思います。
この階層を保持したい:MainActivity -> OuterFrag -> InnerFrag
。したがって、MainActivityは常にOuterFragを呼び出すことができます。
しかし、この階層から変更しないでください:MainActivity -> OuterFrag
この階層:MainActivity -> InnerFrag
MainActivity
はOuterFrag
を失います。
ここに私のサンプルコードがあります。
MainActivity.Java
package com.example.frag;
import Android.os.Bundle;
import Android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().beginTransaction().add(R.id.frameLayout, new OuterFrag()).commit();
getSupportFragmentManager().executePendingTransactions();
System.out.println("Before: "
+ getSupportFragmentManager().findFragmentById(R.id.frameLayout));
((OuterFrag) getSupportFragmentManager().findFragmentById(R.id.frameLayout))
.addInnerFrag();
System.out.println("After: "
+ getSupportFragmentManager().findFragmentById(R.id.frameLayout));
}
}
activity_main.xml
<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/frameLayout"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent" >
</FrameLayout>
OuterFrag.Java
package com.example.frag;
import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
public class OuterFrag extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.outer_frag, container, false);
}
public void addInnerFrag() {
getFragmentManager().beginTransaction().replace(this.getId(), new InnerFrag()).commit();
getFragmentManager().executePendingTransactions();
// getChildFragmentManager().beginTransaction().add(this.getId(), new InnerFrag()).commit();
// getChildFragmentManager().executePendingTransactions();
}
}
outer_frag.xml
<TextView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/textView1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="i am the OUTER frag" />
InnerFrag.Java
package com.example.frag;
import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
public class InnerFrag extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.inner_frag, container, false);
}
}
inner_frag.xml
<TextView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/textView2"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="i am the INNER frag" />
現在、上記のコードはエラーなしで実行できます。しかし、実際にはInnerFrag
の新しい子としてMainActivity
を変更しています。これは、Before:ObjectおよびAfter:Objectが変更された2つのSystem Print Outステートメントによって確認できます。 OuterFrag.Java
では、getChildFragmentManager()
ステートメントの代わりにgetFragmentManager()
ステートメントが実行されると、次のランタイムエラーが発生します。
12-07 02:29:38.406: E/AndroidRuntime(12051): Java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.frag/com.example.frag.MainActivity}: Java.lang.IllegalArgumentException: No view found for id 0x7f070000 (com.example.frag:id/frameLayout) for fragment InnerFrag{46e32748 #0 id=0x7f070000}
getChildFragmentManager()
を使用することは理論的には正しいです。非プログラム的に追加されたフラグメントで使用できます(つまり、activity_main.xml
の<FrameLayout>
を<fragment>
に変更し、属性Android:name="com.example.frag.OuterFrag"
を追加し、最初のgetSupportFragmentManager()
を削除します。 MainActivity.Java
)のステートメント。そして、それは正しい階層を維持しています:MainActivity -> OuterFrag -> InnerFrag
。ただし、元のフラグメント(outer_frag.xml
)の単語を削除することはできません。
結論として、私は常にOuterFrag
のMainActivity
を参照したいと思います。そして、OuterFrag
をプレースホルダーとして機能させて、さまざまなInnerFrag
sをロードします。要するに、プログラムで(動的に)追加されたときに、OuterFrag
でgetChildFragmentManager()
を呼び出したいのです。
結論として、私は常にMainActivityのOuterFragを参照したいと思います。そして、OuterFragが異なるInnerFragsをロードするためのプレースホルダーとして機能するようにします。要するに、プログラムで(動的に)追加された場合、OuterFragでgetChildFragmentManager()を呼び出したいと思います。
これが必要な場合は、OuterFrag
の内容としてコンテナレイアウトを作成し、そのコンテナにInnerFrag
を追加します。 OuterFrag
のレイアウトファイルは次のとおりです。
<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/fragContainer"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
/>
もちろん、必要に応じて、OuterFrag
のレイアウトに他のビューを含めることもできます。 addInnerFrag
メソッドは次のようになります。
public void addInnerFrag() {
getChildFragmentManager().beginTransaction().add(R.id.fragContainer, new InnerFrag()).commit();
getChildFragmentManager().executePendingTransactions();
}
OuterFrag
をメインアクティビティに追加するためのコードは引き続き有効です。