Was ist der Unterschied zwischen getSupportFragmentManager () und getChildFragmentManager ()?

77

Meine Klasse erbt Fragment und kann daher getSupportFragmentManager () nicht verwenden. Ich verwende getChildFragmentManager und es zeigt mir Fehler - IllegalArguementException: Keine Ansicht für ID ... Fehler gefunden.

Jede Anleitung wäre dankbar.

Code zum Aufrufen von AttachmentsListFragment ist

Bundle b = new Bundle();
b.putSerializable("AttachmentsList", msg.attachments);  
        AttachmentListFragment listfrag = new AttachmentListFragment(msg.attachments);
FragmentTransaction transaction = getFragmentManager().beginTransaction();       
transaction.add(R.id.attachmentslistcontainer, listfrag);
transaction.addToBackStack(null);
transaction.commit();

attachmentslayout.xml ist

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/attachmentslistcontainer"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textViewAttachmentHeader"
        style="@style/Normal.Header.Toolbar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/list_separator_background"
        android:ellipsize="end"
        android:gravity="center"
        android:maxLines="2"
        android:text="@string/attachments_header"
        android:textColor="#FFFFFFFF"
        android:textSize="22sp"
        android:textStyle="bold"
        android:visibility="visible" />

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </ListView>

</FrameLayout>

AttachmentsListFragment.java

public class AttachmentListFragment extends ListFragment implements IAttachmentsData {

    ArrayList<Attachments> items = null;
    Integer cellLayoutID;
    Integer index;

    public AttachmentListFragment() {

    }

    public AttachmentListFragment(ArrayList<Attachments> items) {
        this.items = items;
        Log.i("Logging", "Items size" + items.size()); //$NON-NLS-1$
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle bundle;
        if (savedInstanceState != null) {
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        //super.onCreateView(inflater, container, savedInstanceState);

        //  setContentView(R.layout.attachmentslayout);
        View view = inflater.inflate(R.layout.attachmentslayout, container, false);
        return view;
    }


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setListAdapter(new AttachmentAdapter(
                getActivity().getApplicationContext(),
                R.layout.attachmentslistcellcontent,
                items));
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // TODO Auto-generated method stub
        super.onListItemClick(l, v, position, id);
        index = position;
        Intent intent = new Intent();
        Bundle b = new Bundle();
        b.putByteArray("Data", items.get(position).getImageData());
        intent.putExtras(b);
    }


    public byte[] getData() {
        // TODO Auto-generated method stub
        if (items != null && index < items.size()) {

            return items.get(index).getImageData();
        }
            return null;
    }

}
NinjaCoder
quelle
2
Bitte posten Sie die gesamte Methode und / oder Klasse, in der Sie "getChildFragmentManager" aufrufen.
WindyB

Antworten:

152

Die Definition von getChildFragmentManager()ist:

Geben Sie einen privaten FragmentManager zurück, um Fragmente in diesem Fragment zu platzieren und zu verwalten.

Inzwischen lautet die Definition von getFragmentManager()(oder in diesem Fall getSupportFragmentManager()):

Geben Sie den FragmentManager für die Interaktion mit Fragmenten zurück, die der Aktivität dieses Fragments zugeordnet sind.

Grundsätzlich besteht der Unterschied darin, dass Fragmente jetzt ein eigenes internes haben FragmentManager, das Fragmente verarbeiten kann. Der untergeordnete FragmentManager verarbeitet Fragmente, die nur in dem Fragment enthalten sind, zu dem er hinzugefügt wurde. Der andere FragmentManager ist im gesamten enthalten Activity.

In diesem Fall haben Sie vermutlich die Fragmente zum FragmentManager der Aktivität hinzugefügt. Sie erhalten den untergeordneten FragmentManager, der nicht das enthält, wonach Sie suchen. Daher erhalten Sie die Ausnahme, weil das Fragment mit der angegebenen ID nicht gefunden werden kann, da es sich in einem anderen FragmentManager befindet.

DeeV
quelle
3
Ich habe versucht, getChildFragmentManager zu verwenden. Aber es zeigt auch die gleiche Ausnahme
NinjaCoder
1
Ich dachte, Sie sagten, Sie würden bereits getChildFragmentManager verwenden.
DeeV
Was bewirkt die Schaltfläche "Zurück", wenn ich den getSupportFragmentManager verwende, um ein untergeordnetes Fragment zu erstellen, sodass das übergeordnete Element das untergeordnete Element enthält und beide sichtbar / im Vordergrund sind? springt es vom Elternteil ab? oder das Kind? etc.?
Pinkerton
1
@Rai getSupportFragmentManagerund getFragmentManagersind beide Fragmentmanager auf der obersten Ebene Activity. Das Fragment, das Sie technisch hinzufügen, ist nach der hier beschriebenen Definition kein "untergeordnetes Fragment". Sie sind Fragmente, die von der Aktivität behandelt werden. Jedes Fragment, das Sie auf dem Backstack eines der von der Aktivität verwalteten Manager veröffentlichen, wird auf "Zurück" angezeigt.
DeeV
24

getFragmentManagergehören zu Activity
getChildFragmentManagergehörenFragment

Beispiel wir eine App haben , die haben MainActivity, Fragment1, Fragment2, container_view_on_mainist ein Layout inactivty_main.xml

Zur Anzeige Fragment1 auf MainActivitywir müssen verwendengetSupportFragmentManager()

getSupportFragmentManager().beginTransaction().replace(R.id.container_view_on_main, Fragment1.newInstance());

Zum Anzeigen Fragment2 von Fragment1uns 2 - Wege haben

VERWENDEN getFragmentManager()

getFragmentManager().beginTransaction().replace(R.id.container_view_on_main, Fragment1.newInstance());

VERWENDEN getChildFragmentManager()

Erstens haben wir ein Layout mit ID erstellen container_view_on_fragment1innen fragment1.xml, dann

getChildFragmentManager().beginTransaction().replace(R.id.container_view_on_fragment1, Fragment2.newInstance()).commit();

FAZIT

Ich denke, wir sollten diese Demo verwenden, getFragmentManager()wenn wir von Fragment1zu gehen , Fragment2da sie einfach und gut für die Leistung ist ( Fragment1hört auf, wenn sie Fragment2geöffnet ist).

Wann verwenden wir getChildFragmentManager()?
Beispiel: Sie MainActivityhaben eine Seite ViewPagermit 3 Seiten. Innerhalb jeder Seite müssen Sie ein Fragment ersetzen.

MEHR
- getParentFragment ()
getFragmentManager() => return null
getChildFragmentManager() => immer Root-Fragment zurückgeben ( Fragment1in der Demo gehen wir sogar zu Fragment3 ,, ...)

Diese Antwort basiert auf meinem Verständnis. Bitte korrigieren Sie mich, wenn ich falsch liege. Hoffe es hilft

Phan Van Linh
quelle
2

Wenn Sie ein Fragment haben möchten, das sich wie ein Container mit Fragmenten verhält, müssen Sie die Methode getChildFragmentManager des Fragments verwenden. Wenn Sie den getSupportFragmentManager verwenden, verwenden Sie grundsätzlich den Fragmentmanager, der sich wie der Aktivitätslebenszyklus verhält und nicht wie Ihr Fragment.

Zum Beispiel hatte ich ein Fragment, das einen ViewPager enthielt - es heißt CollectionsFragment. Ich hatte also 3 Fragmente als Registerkarten darin: AllCollectionsFragment, MyCollectionsFragment, FavouriteCollectionsFragment. Und ich habe dem FragmentStatePagerAdapter, den ich verwendet habe, getActivity (). GetSupportFragmentManager () gegeben.

Dies führte also zu folgendem Verhalten: Die Methoden onDestroyView / onDestroy / onDetach / onStop der 3 Tab-Fragmente wurden nicht aufgerufen. Als ich auf getChildFragmentManager umstieg, war alles in Ordnung.

Wenn Sie möchten, können Sie in den Dokumenten nach den beiden Methoden suchen:

getChildFragmentManager (): Gibt einen privaten FragmentManager zurück, um Fragmente in diesem Fragment zu platzieren und zu verwalten.

getSupportFragmentManager (): Gibt den FragmentManager für die Interaktion mit Fragmenten zurück, die der Aktivität dieses Fragments zugeordnet sind.

Vinod Pattanshetti
quelle