FragmentManager

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • FragmentManager

    Hallo,

    ich habe eine Activity (AppCompatActivity) in der ein FrameLayout durch ein Fragment ausgetauscht wird.

    Java-Quellcode

    1. MyFragment fragment = new MyFragment();
    2. FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    3. transaction.replace(R.id.id_framelayout, fragment);
    4. transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    5. //transaction.addToBackStack(null);
    6. transaction.commit();

    In diesem Fragment (MyFragment) ist ein ViewPager mit 3 Fragmenten, welche in einem Adapter zum Activity-FragmentManager hinzugefügt werden.
    Also stecken im FragmentManager der Activity 4 Views.
    Wenn ich nun das Handy drehe stürtzt meine App ab und ich weiss nicht warum.
    Der Absturz passiert in onCreate der Activity, den im Bundle savedInstanceState sind alle 4 Views vermerkt.

    Wenn ich vor dem Handy drehen versuche die 3 Views zu entfernen, hat dies keinen Effekt denn sie bleiben im FragmentManager.

    Was mache ich falsch oder muss ich einen separaten FragmentManager in MyFragment erstellen damit die 3 Views aus dem ViewPager isoliert sind.

    Ich verstehe das nicht, denn ohne den ViewPager funktioniert das drehen, wenn nur ein Fragment im FragmentManager ist.



    Grüße Eddi
  • Hallo
    Um hier eine sinnvolle aussage machen zu können solltest du uns den Code der MyFragment Klasse zeigen.

    Ich verstehe auch nicht warum du ein Fragment erstellt und in diesen wieder drei Fragmente mit einen Viewpager.

    Ohne Code kommen wir hier nicht weiter.


    PS.

    In diesem Fragment (MyFragment) ist ein ViewPager mit 3 Fragmenten, welche in einem Adapter zum Activity-FragmentManager hinzugefügt werden.
    Wenn dem wirklich so ist kann das nicht gehen.


    Du hast eine Activity mit einem Layout in dem ist eine FrameLayout das als Container für das Fragment dient.

    Wenn du in der Klasse MyFragment wieder ein Fragment startest oder einen Viewpager benutzt, dann muss in dem Layout was du in der MyFragment Klasse lädst wieder ein Container, ViewPager sein. Und in genau diesen Container sollte die Drei Fragmente geladen werden. Nicht in dem Container des Activity Layouts.


    Mit dem Activity-FragmentManager haben die drei Fragmente nichts mehr zu tun.

    Hoffe das es etwas klarer geworden ist.
    Ein Feedback auf Tipps ist auch schön. :P

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von jogimuc ()

  • Hallo jogimuc,

    ich hab mal den Code zusammengefasst damit es leserlich bleibt.

    Java-Quellcode

    1. public class Startseite extends AppCompatActivity
    2. {
    3. protected void onCreate(Bundle savedInstanceState)
    4. {
    5. super.onCreate(savedInstanceState);
    6. setContentView(R.layout.activity_startseite);
    7. m_framelayout = findViewById(R.id.id_framelayout);
    8. m_fragment_termine = new Termine();
    9. FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    10. transaction.replace(R.id.id_framelayout, m_fragment_termine);
    11. transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    12. //transaction.addToBackStack(null);
    13. transaction.commit();
    14. }
    15. }
    16. public class Termine extends Fragment
    17. {
    18. public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    19. {
    20. View root_view = inflater.inflate(R.layout.fragment_termine, container, false);
    21. m_viewPager = root_view.findViewById(R.id.id_viewPager);
    22. m_fragment_termine_1 = new TermineSub();
    23. m_fragment_termine_2 = new TermineSub();
    24. m_fragment_termine_3 = new TermineSub();
    25. m_adapter_fragmente = new AdapterFragmente(getActivity().getSupportFragmentManager());
    26. m_adapter_fragmente.addFragment(m_fragment_termine_1);
    27. m_adapter_fragmente.addFragment(m_fragment_termine_2);
    28. m_adapter_fragmente.addFragment(m_fragment_termine_3);
    29. m_viewPager.setAdapter(m_adapter_fragmente);
    30. }
    31. }
    32. public class TermineSub extends Fragment
    33. {
    34. ...
    35. }
    36. public class AdapterFragmente extends FragmentStatePagerAdapter
    37. {
    38. public final List<Fragment> mFragmentList = new ArrayList<>();
    39. private FragmentManager mFragmentManager;
    40. public AdapterFragmente(FragmentManager manager)
    41. {
    42. super(manager);
    43. this.mFragmentManager = manager;
    44. mFragmentList.clear();
    45. }
    46. @Override
    47. public Fragment getItem(int position)
    48. {
    49. return mFragmentList.get(position);
    50. }
    51. @Override
    52. public int getCount()
    53. {
    54. return mFragmentList.size();
    55. }
    56. public void addFragment(Fragment fragment)
    57. {
    58. mFragmentList.add(fragment);
    59. notifyDataSetChanged();
    60. }
    61. public void deleteFragment(Fragment fragment)
    62. {
    63. mFragmentList.remove(fragment);
    64. // FragmentTransaction transaction = mFragmentManager.beginTransaction(); //(funktioniert nicht, fragmente werden nicht gelöscht)
    65. // transaction.remove(fragment);
    66. // transaction.commit();
    67. notifyDataSetChanged();
    68. }
    69. }
    Alles anzeigen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Eddi ()

  • Hallo
    Habe mir mal deinen Code angesehen.


    Frage wann und von wo wird die Methode „deleteFragment“ , im Adapter, aufgerufen was soll die überhaupt ? Wieso müssen die Fragmente gelöscht werden? Das macht der GC eigentlich selber wenn die Instanzen nicht merhr gültig sind.

    Was soll überhaupt das „notifyDataSetChanged()“ in der Add Methode im Adapter?

    Auch ein „notify“ in der deleteFragment Methode finde ich sinnlos.
    Die Methode notifyDataSetChanged() innerhalb des Adapters aufzurufen ist für mich sinnlos.
    Die Methode ist dafür gedacht von außerhalb das neu Zeichnen zu veranlassen. Nicht intern sich selber.


    Warum musst du die liste der Fragments im Constructor löschen wird nicht problematisch sein nur wieso?


    Ob das mit dem Fragment Manager aus der Activity so richtig ist kann ich nicht sagen. Habe ich bis jetzt noch nicht gemacht ein Fragment im Fragment.
    Da aber es beim ersten Aufbau geht wird das wohl nicht der Grund des Absturz sein.


    Welcher Fehler kommt den beim Absturz?
    Wo in welcher Methode passierst es denn. Mache dir doch ein paar Logs um das nach zu vollziehen.


    Bein drehen wird ja die Activity neu gestartet und auch die onCreate wieder durchlaufen.
    Es müssten somit auch deine Fragmente wider neu aufgerufen werden. Und auch der Pager in dem ersten Fragment.


    Was ich aber bei dem ersten Fragment nicht richtig finde ist das du es nicht lädst sonder ersetzt. „transaction.replace“ zu dem Zeitpunkt ist eigentlich noch kein Fragment da zum austauschen.
    Ich würde transaction.add( … machen. Das erste Fragment sollte immer add sein und anschießend tauschen was du ja gar nicht machst denn du hast ja nur ein Fragment.


    Vielleicht machst du auch etwas in der onCreate was beim zweiten Aufruf zum Absturz führt.
    Ein Feedback auf Tipps ist auch schön. :P
  • Hallo jogimuc,

    der Absturz war in der OnCreate der Activity "Startseite" beim Zugriff auf das Bundle savedInstanceState.
    Ich hab die notifyDataSetChanged und deleteFragment entfernt und jetzt funktioniert es.


    Jetzt hab ich aber ein weiteres Problem.

    Beim drehen des Handys wird ja die Activity neu erstellt aber die Fragmente im FragmentManager bleiben bestehen und es kommen 3 neue hinzu.

    (die beim Start ja erstellt werden) Nun habe ich wenn ich mehrmals drehe jedesmal mehr fragmente und alle werden neu initialisiert.

    Daher wollte ich die alten Fragmente löschen. Oder wie kann ich prüfen welche Fragemente aktiv sind.


    habs jetzt so:
    Ich hab jetzt die Fragmente die vom FragmentManager automatisch erstellt werden und den standard construktor durchlaufen, nicht initialisiert.
    Ich habe nur die 3 neuen Fragmente die durch einen erweiterten constructor erzeugt werden mit daten gefüllt, somit denke ich habe ich das Problem gelöst ? :whistling:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Eddi ()

  • Hallo schon zu hören das es geht.

    Nur wundert es mich das nach dem drehen das die Fragmente noch da sein sollen.

    Vom Fragmentmanager werden keine Fragmente automatisch erstellt das macht du selber in der onCreateView .
    Eigentlich müsste die auch beim drehen wieder durchlaufen werden . kannste mit einem log mal prüfen.

    damit erstellt du die Fagmente.
    m_fragment_termine_1 = new TermineSub();
    m_adapter_fragmente.addFragment(m_fragment_termine_1);

    Wenn die Instanz nicht mehr gültig ist sollte das der GC freigeben.


    Zeige mal wie du das mit dem Fragmentmanager und Constructor machst.



    Kannst ja vorher prüfen ob die Objekte existieren vor dem neu erstellen.
    if (m_fragment_termine_1 == Null{
    m_fragment_termine_1 = new TermineSub();
    m_adapter_fragmente.addFragment(m_fragment_termine_1);
    }
    Ein Feedback auf Tipps ist auch schön. :P