Új hozzászólás Aktív témák

  • thon73
    tag

    Bocs, csak úgy értettem, hogy volt-e már valakinek ehhez hasonló tapasztalata. Neki is láttam egy egyszerűsített tesztkódot írni (az enyém meglehetősen hosszú).
    Ez a teszt fragment, egyetlen metódus:

    public class TestFragment extends Fragment
    {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
    TextView tv = new TextView(getActivity());
    tv.setText("Hello világ!");
    return tv;
    }
    }

    És a lényeg: az activity:

    public class MainActivity extends FragmentActivity
    {

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    FrameLayout fl = new FrameLayout(this );
    fl.setId(1234);
    setContentView(fl);
    }

    @Override
    public void onResumeFragments()
    {
    super.onResumeFragments();

    FragmentManager fragmentManager = getSupportFragmentManager();

    TestFragment test = (TestFragment)fragmentManager.findFragmentByTag("TEST");
    if (test == null)
    {
    test = new TestFragment();
    }

    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.add(1234, test, "TEST");
    fragmentTransaction.commit();
    }


    @Override
    public void onPause()
    {
    super.onPause();

    FragmentManager fragmentManager = getSupportFragmentManager();

    TestFragment test = (TestFragment)fragmentManager.findFragmentByTag("TEST");
    if (test!=null)
    {
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    // fragmentTransaction.detach(test);
    fragmentTransaction.remove(test);
    fragmentTransaction.commit();
    }
    }

    }

    ((Igazából ezeken a kódokon kívül az eclipse saját indítókódján semmit sem kell változtatni, mert a View-k dinamikusan jönnek létre. A rengeteg Log-ot kitöröltem, de akár minden metódus figyelhető a LogCat-ben.))

    A LÉNYEG:

    Sztem. az indítás során az onResumeFragments-ben hozzáadjuk a "TEST" fragmentet,
    leállításnál az onPause-ben eldobjuk. (Ha akarjuk, akkor detach is lehet.)

    A REMOVE UTÁN SZERINTEM A FRAGMENTNEK EL KELLENE PUSZTULNIA A DESTROY FOLYAMÁN!

    Ehhez képest újraindítás után hibaüzenet:
    java.lang.RuntimeException: Unable to resume activity {.fragmenttest.MainActivity}: java.lang.IllegalStateException: Fragment already added: TestFragment{40525cf0 #0 id=0x4d2 TEST}

    Vagyis az eldobott Fragmentünk "visszajött".

    Ugyanez történik ID és Tag alapú keresésnél is: az eldobott Fragment megjelenik
    Ha két (landscape és portrait) layout között váltogatok, akkor még hibaüzenet sem jön, csak a Fragmentek sokasodnak.
    ((Világos, ha a remove átkerül a legelejére, akkor nem lesz hiba, de a Fragment megmarad))

    SZERINTEM:
    A Fragment-ek NEM objektumként működnek, hanem sokkal jobban hasonlítanak az Activity-ra. Vagyis: létrehozás után (ez történik objektumok módjára), mindvégig megmaradnak, csak ide-oda kapcsolgathatjuk őket.
    Az onRetain...-nál annyi különbség lehet, hogy ott érinetetlenül maradnak meg, itt meg a View újra készül.

    Ez azért gond, mert ha egyszer egy Fragmentet valamelyik View-ba bekapcsoltunk, akkor ragaszkodik a saját View-jához, más View ID esetén hibát dob.

    Képzeljünk el egy szituációt: bal oldalon a lista, jobbra az egyes elemek, külön fragmentben. Ha ezt EGY activityvel oldjuk meg, akkor NÉGY fragmentet kell kezelnünk (2 landscape, 2 külön portrait módban) VAGY ha ugyanazt az Id-t adjuk meg a két külön layout-ban lévő fragmentet fogadó View-nak, akkor csak KÉT fragmentet kell kezelnünk.
    Tudom, hogy a KÉT ACTIVITY-vel való kezelést preferálják, de 1. ettől nem tudom meg, miért nem tűnnek el a fragmentek. ((2. Az activity-k közötti kommunikáció miatt ez a megoldás most nem az igazi nekem (de ez a teszt szempontjából lényegtelen))

    Bocs, ha nem teljesen érthető ez, igyekeztem nagyon rövidíteni a kódot. De már csak azért is hajt a kíváncsiság, hogy ez miként műxik.

    Nem tudok elszakadni a felszaporodó fragmentek problémájától...
    Sehol nem írják ezt a megoldást, pedig nekem minden bajomat megoldotta. Sőt! Portrait-ból Landscape-be való visszafordításnál a másodlagos Fragmentben lévő adatok is megmaradtak! (Lévén ugyanaz a Fragment jelent meg máshol)

    layout/main.xml

    <FrameLayout
    android:id="@+id/portrait"
    ... >
    <FrameLayout
    android:id="@+id/list_frame"
    ... />
    <FrameLayout
    android:id="@+id/edit_frame"
    ... />
    </FrameLayout>

    layout-land/main.xml

    <LinearLayout
    android:id="@+id/landscape"
    ... >
    <FrameLayout
    android:id="@+id/list_frame"
    ... />
    <FrameLayout
    android:id="@+id/edit_frame"
    ... />
    </LinearLayout>

    Vagyis: ugyanazok az id-k mind landscape,mind portrait módban. Természetesen portrait módban a két frame "átfedi" egymást, tehát a program logikájának kell megoldani, hogy hol az EDIT, hol a LIST fragment legyen felcsatolva a saját (átfedő) Frame-jébe.
    Az egész program (ill. ez a része) csak KÉT Fragment Példányt tartalmaz. És egy Activity van (ez volt a cél)

    Szól ez ellen a megvalósítás ellen vmilyen. érv? Nekem működőképesnek tűnik. Mivel a két layout egyszerre nem valósul meg, az id-k sem akadnak össze. Mindkét frame mindig a "saját" frame-jébe lesz bekapcsolva, mindig a saját tag-jével jelölve. Nincs változás, nincs hibaüzenet. Mivel nem a frame-ek kapcsolnak ki/be, az animációk ugyanúgy látszanak.
    Mégsem olvastam ilyen megoldást sehol. Van ezzel vmi baj szerintetek?
    Tényleg senkinek nem volt még nehézsége a fragmentek megvalósításával? Tényleg senkinél nem szaporodtak még fel az elforgatások során? :F

Új hozzászólás Aktív témák