Fragment innerhalb des Fragments

Ich brauche Hilfe in Bezug auf die Arbeit an Fragment in Fragment, tatsächlich habe ich ein Problem mit dem Zurück-Button konfrontiert. Application Hauptbildschirm hat Schaltflächen und drücken auf jeder Schaltfläche Ansicht ersetzen mit neuen Fragment (und das Fragment in einem anderen Fragment enthalten), dynamisch Hinzufügen / Ersetzen Fragment funktioniert gut, indem Taste1 Fragment ersetzt ersetzt, passiert auch beim Drücken der Taste, aber wenn ich drücke Der Button hat wieder eine Ausnahme:

"Duplicate id 0x7f05000a, tag null, or parent id 0x7f050009 with another fragment for com........ fragmentname" 

bedeutet Fragment oder innere Fragmente sind bereits hinzugefügt und ich versuche, sie wieder hinzuzufügen, jeder hat Idee, wie man mit Fragment innerhalb Fragment arbeiten und ohne Probleme hin und her bewegen, danke für die Unterstützung.

MainActivity, wo Fragmente dynamisch hinzugefügt und ersetzt werden.

  public class FragmentInsideFragmentTestActivity extends Activity { private Button button1; private Button button2; private Button button3; private Button button4; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); button1 =(Button) this.findViewById(R.id.button1); button1.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { onButtonClick(view); } }); button2 =(Button) this.findViewById(R.id.button2); button2.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { onButtonClick(view); } }); button3 =(Button) this.findViewById(R.id.button3); button3.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { onButtonClick(view); } }); button4 =(Button) this.findViewById(R.id.button4); button4.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { onButtonClick(view); } }); } public void onButtonClick(View v) { Fragment fg; switch (v.getId()) { case R.id.button1: fg=FirstFragment.newInstance(); replaceFragment(fg); break; case R.id.button2: fg=SecondFragment.newInstance(); replaceFragment(fg); break; case R.id.button3: fg=FirstFragment.newInstance(); replaceFragment(fg); break; case R.id.button4: fg=SecondFragment.newInstance(); replaceFragment(fg); break; } } private void replaceFragment(Fragment newFragment) { FragmentTransaction trasection = getFragmentManager().beginTransaction(); if(!newFragment.isAdded()){ try{ //FragmentTransaction trasection = getFragmentManager().beginTransaction(); trasection.replace(R.id.linearLayout2, newFragment); trasection.addToBackStack(null); trasection.commit(); }catch (Exception e) { // TODO: handle exception //AppConstants.printLog(e.getMessage()); } }else trasection.show(newFragment); } } 

Hier ist Layout: main.xml

   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"         

Ich hoffe, ich habe versucht, mein Problem zu lösen.

Solutions Collecting From Web of "Fragment innerhalb des Fragments"

AFAIK, Fragmente können keine anderen Fragmente halten.


AKTUALISIEREN

Mit aktuellen Versionen des Android Support-Pakets – oder nativen Fragmenten auf API Level 17 und höher – können Sie Fragmente mithilfe von getChildFragmentManager() . Beachten Sie, dass dies bedeutet, dass Sie die Version des Android-Supportpakets von Fragmenten in den API-Leveln 11-16 verwenden müssen, da diese Version zwar keine native Version von Fragmenten auf diesen Geräten, aber nicht getChildFragmentManager() .

Seit Android 4.2 (API 17) sind verschachtelte Fragmente verfügbar http://developer.android.com/about/versions/android-4.2.html#NestedFragments

Um ein Fragment in ein anderes Fragment zu platzieren, verwenden Sie getChildFragmentManager ()

Es ist auch in der Support-Bibliothek verfügbar!

Bildbeschreibung hier eingeben

Ich brauchte etwas mehr Kontext, also machte ich ein Beispiel, um zu zeigen, wie das gemacht wird. Das Hilfreichste, was ich während der Vorbereitung gelesen habe, war folgendes:

  • Fragmente erstellen und verwenden

Aktivität

activity_main.xml

Fügen FrameLayout Ihrer Aktivität ein FrameLayout , um das übergeordnete Fragment zu FrameLayout .

 < ?xml version="1.0" encoding="utf-8"?>     

Hauptaktivität.java

Laden Sie das übergeordnete Fragment und implementieren Sie die Fragmentlistener. (Siehe Fragmentkommunikation .)

 import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AppCompatActivity; public class MainActivity extends AppCompatActivity implements ParentFragment.OnFragmentInteractionListener, ChildFragment.OnFragmentInteractionListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Begin the transaction FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.parent_fragment_container, new ParentFragment()); ft.commit(); } @Override public void messageFromParentFragment(Uri uri) { Log.i("TAG", "received communication from parent fragment"); } @Override public void messageFromChildFragment(Uri uri) { Log.i("TAG", "received communication from child fragment"); } } 

Elternfragment

fragment_parent.xml

Fügen Sie einen weiteren FrameLayout Container für das FrameLayout Fragment hinzu.

 < ?xml version="1.0" encoding="utf-8"?>      

ParentFragment.java

Verwenden Sie getChildFragmentManager in onViewCreated , um das getChildFragmentManager onViewCreated einzurichten.

 import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; public class ParentFragment extends Fragment { private OnFragmentInteractionListener mListener; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_parent, container, false); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { Fragment childFragment = new ChildFragment(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.replace(R.id.child_fragment_container, childFragment).commit(); } @Override public void onAttach(Context context) { super.onAttach(context); if (context instanceof OnFragmentInteractionListener) { mListener = (OnFragmentInteractionListener) context; } else { throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener"); } } @Override public void onDetach() { super.onDetach(); mListener = null; } public interface OnFragmentInteractionListener { // TODO: Update argument type and name void messageFromParentFragment(Uri uri); } } 

Kind Fragment

fragment_child.xml

Hier gibt es nichts Besonderes.

 < ?xml version="1.0" encoding="utf-8"?>    

KindFragment.java

Auch hier gibt es nichts Besonderes.

 import android.support.v4.app.Fragment; public class ChildFragment extends Fragment { private OnFragmentInteractionListener mListener; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_child, container, false); } @Override public void onAttach(Context context) { super.onAttach(context); if (context instanceof OnFragmentInteractionListener) { mListener = (OnFragmentInteractionListener) context; } else { throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener"); } } @Override public void onDetach() { super.onDetach(); mListener = null; } public interface OnFragmentInteractionListener { // TODO: Update argument type and name void messageFromChildFragment(Uri uri); } } 

Anmerkungen

  • Die Support-Bibliothek wird verwendet, damit verschachtelte Fragmente vor Android 4.2 verwendet werden können.

Fragmente können innerhalb anderer Fragmente hinzugefügt werden, aber dann müssen Sie sie jedes Mal aus dem übergeordneten Fragment entfernen, wenn die Methode onDestroyView () des übergeordneten Fragments aufgerufen wird. Und fügen Sie es erneut in der OnCreateView () – Methode des Parent Fragments hinzu.

Mach es einfach so:

 @Override public void onDestroyView() { FragmentManager mFragmentMgr= getFragmentManager(); FragmentTransaction mTransaction = mFragmentMgr.beginTransaction(); Fragment childFragment =mFragmentMgr.findFragmentByTag("qa_fragment") mTransaction.remove(childFragment); mTransaction.commit(); super.onDestroyView(); } 

Ich habe dieses Problem getriggers. Sie können Support-Bibliothek und ViewPager . Wenn Sie nicht mit Gesten wischen müssen, können Sie das Wischen deaktivieren. Also hier ist ein Code, um meine Lösung zu verbessern:

 public class TestFragment extends Fragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.frag, container, false); final ArrayList list = new ArrayList(); list.add(new TrFrag()); list.add(new TrFrag()); list.add(new TrFrag()); ViewPager pager = (ViewPager) v.findViewById(R.id.pager); pager.setAdapter(new FragmentPagerAdapter(getChildFragmentManager()) { @Override public Fragment getItem(int i) { return list.get(i); } @Override public int getCount() { return list.size(); } }); return v; } } 

PS Es ist ein hässlicher Code für den Test, aber es verbessert, dass es möglich ist.

Das PPS Inside-Fragment ChildFragmentManager sollte an ViewPagerAdapter

Sie können die function getChildFragmentManager() verwenden.

Beispiel:

Elternfragment:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { rootView = inflater.inflate(R.layout.parent_fragment, container, false); } //child fragment FragmentManager childFragMan = getChildFragmentManager(); FragmentTransaction childFragTrans = childFragMan.beginTransaction(); ChildFragment fragB = new ChildFragment (); childFragTrans.add(R.id.FRAGMENT_PLACEHOLDER, fragB); childFragTrans.addToBackStack("B"); childFragTrans.commit(); return rootView; } 

parent_fragment.xml ( parent_fragment.xml ):

 < ?xml version="1.0" encoding="utf-8"?>    

Kinderfragment:

 public class ChildFragment extends Fragment implements View.OnClickListener{ View v ; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { // TODO Auto-generated method stub View rootView = inflater.inflate(R.layout.child_fragment, container, false); v = rootView; return rootView; } @Override public void onClick(View view) { } } 

Sie können FrameLayout zum Fragment hinzufügen und es bei der Initialisierung durch ein anderes Fragment ersetzen.

Auf diese Weise könnten Sie das andere Fragment als innerhalb des ersten Fragments betrachten.

Verwenden Sie getChildFragmentManager (), folgen Sie dem Link: Nested Fragment

Es gibt keine Unterstützung für MapFragment, Android-Team sagt, dass es seit Android 3.0 arbeitet. Hier finden Sie weitere Informationen zum Problem http://code.google.com/p/android/issues/detail?id=15347&utm_source=buffer&buffer_share=acc72 Aber was können Sie tun, indem Sie ein Fragment erstellen, das eine MapActivity zurückgibt? Hier ist ein Codebeispiel. Danke an inazaruk: https://github.com/inazaruk/examples/tree/master/MapFragmentExample

Wie es funktioniert:

-MainFragmentActivity ist die Aktivität, die FragmentActivity erweitert und zwei MapFragments hostet. -MyMapActivity erweitert MapActivity und verfügt über MapView. -LocalActivityManagerFragment hostet LocalActivityManager. -MyMapFragment erweitert LocalActivityManagerFragment und erstellt mit Hilfe von TabHost die interne Instanz von MyMapActivity. Wenn Sie Zweifel haben, lassen Sie es mich bitte wissen

In verschachtelten Fragmenten werden die verschachtelten (s) nur unterstützt, wenn sie programmgesteuert generiert werden! Zu diesem Zeitpunkt wird kein verschachteltes Fragment-Layout im XML-Layout-Schema unterstützt!

Es ist nicht kompliziert. Wir können getFragmentManager () hier nicht verwenden. Um Fragmente in einem Fragment zu verwenden, verwenden wir getChildFragmentManager (). Die Ruhe wird gleich sein.

Hallo, ich habe dieses Problem getriggers, indem ich per Fragment in ein anderes Layout gesetzt habe. Und ich habe gerade das zugehörige Layout sichtbar gemacht und die anderen Sichtbarkeiten verschwinden lassen.

Ich meine:

 < ?xml version="1.0" encoding="utf-8"?>              . . .  

Ich gehe davon aus, dass Sie Ihre Seite öffnen werden, wenn Sie auf die Schaltfläche 1 klicken. Sie können die Sichtbarkeit des Fragments bei Klickaktionen steuern. Sie können verwandtes Layout sichtbar machen und die anderen entfernen und mit Fragment Manager können Sie Ihr Fragment übernehmen. Und da die Ansicht, die Sichtbarkeit hat: weg ist unsichtbar, und sie braucht keinen Platz für Layout-Zwecke. Ich denke, dieser Ansatz verursacht kein Platzproblem.

PS: Ich habe gerade versucht zu erklären, dass mein Lösungscode Syntaxerrors oder unvollständige Struktur hat.

Das kann denen helfen, die an Kotlin arbeiten. Sie können die Extension-function verwenden, also erstellen Sie eine Kotlin-Datei, sagen wir “util.kt” und fügen Sie diesen Code hinzu

 fun Fragment.addChildFragment(fragment: Fragment, frameId: Int) { val transaction = childFragmentManager.beginTransaction() transaction.replace(frameId, fragment).commit() } 

Sagen wir, das ist die class des Kindes

 class InputFieldPresentation: Fragment() { var views: View? = null override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { views = inflater!!.inflate(R.layout.input_field_frag, container, false) return views } override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) ... } ... } 

Jetzt können Sie die Kinder so zum Vaterfragment hinzufügen

  FatherPresentation:Fragment() { ... override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val fieldFragment= InputFieldPresentation() addChildFragment(fieldFragment,R.id.fragmet_field) } ... } 

wobei R.id.fragmet_field die ID des Layouts ist, das das Fragment enthält. Dieses Lyout befindet sich natürlich innerhalb des Vaterfragments. Hier ist ein Beispiel

vater_fragment.xml :

  ...   ...