getChildFragmentManager () на программно (динамически) добавленных фрагментах?
как использовать (или "Можем ли мы использовать") getChildFragmentManager()
на программно (динамически) добавил Fragment
s?
вот мой пример.
у меня есть один MainActivity
, одно OuterFrag
и один InnerFrag
. Я добавлю OuterFrag
to 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
. Это можно проверить с помощью двух системных операторов Print Out, которые изменяют объект Before: Object и объект After: Object. В 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
' s <FrameLayout>
to <fragment>
добавить атрибут android:name="com.example.frag.OuterFrag"
, и уберите первую getSupportFragmentManager()
заявление MainActivity.java
). И он сохраняет правильную иерархию:MainActivity -> OuterFrag -> InnerFrag
. Но слова оригинального фрагмента (outer_frag.xml
) никогда не может быть отнято.
в заключение, я хочу, чтобы ссылка OuterFrag
на MainActivity
всегда. И я хочу!--10--> выступать в качестве заполнителя для загрузки различных InnerFrag
s. Короче говоря, я хочу позвонить getChildFragmentManager()
на OuterFrag
, когда он добавляется программно (динамически).
2 ответов
в заключение я хочу всегда ссылаться на OuterFrag в MainActivity. И я хочу OuterFrag выступать в качестве заполнителя для загрузки разных Иннерфрагс. Короче говоря, я хочу вызвать getChildFragmentManager () в OuterFrag, когда он добавляется программно (динамически).
если вы хотите этого, то сделайте свой 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
основной деятельности остается в силе.
Если вы хотите позвонить addInnerFrag()
в своем OuterFrag.java
код, вы можете сделать это так:
OuterFrag.java:
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
addInnerFrag();
}