[ERLEDIGT] Probleme mit Rückkehr zu altem Fragment

P

Parg

App-Anbieter (kostenlos)
162
Hallo,

derzeit entwickle ich eine App, die die GPS Geschwindigkeit des Smartphones abfragt und darauf reagiert. Konkret sieht es so aus, dass ab 25 km/H vom Modus "Laufend" in "Fahrend" gewechselt wird. Wenn diese 25 km/h nun wieder unterschritten sind, startet ein Countdown. Wenn man für die Dauer des Countdowns unter den 25 km/h bleibt, wechselt man wieder in den Modus "Laufend", ansonsten zurück zu "Fahrend". Funktioniert soweit hervorragend.

Nun zum Problem:

Ich habe eine Activity und zwei Fragmente, welche ich über den klassischen Navigation Drawer auswähle. Das erste Fragment zeigt die oben genannten Modi, sowie den Countdown an. Das zweite ist nur eine Art Impressum.
Alles funktioniert so lange, bis man von Fragment 2 zurück zu Fragment 1 wechselt. Danach wird der Modus (egal was es vorher war), wieder auf laufend gesetzt und der Countdown startet nicht mehr (Zumindest zeigt die TextView nur noch den Initialzustand des Countdowns an, obwohl er runterzählen müsste).

Den ganzen Logik Code (LocationManager, State Handler,... ) habe ich in der MainActivity. Die Fragments dienen nur zur Darstellung.
Die Kommunikation von Activity --> Fragment erfolgt über ein Interface.
Ein neuer Modus wird dem Fragment über fragmentCommunicator.changeStateIcon(INT) übergeben.
Die Countdown zahlen werden per fragmentCommunicator.passCountdownValues(INT) bei onTick des Countdown Objekts übergeben.


Wenn ich von Frag 1 in Frag 2 wechsel (und umgekehrt) bleibt ja die Activity erhalten, oder? d.h. auch das Countdown Objekt bleibt erhalten.
Was muss ich nun tun, damit Fragment 1 bei onResume weitermacht wie vorher. Ich habe schon versucht über savedInstanceState den aktuellen Modus zu sichern, leider ohne Erfolg.

Das mit dem Countdown erkläre ich mir so, dass bei dem Fragmentwechsel (replace) die Verbindung von Activity zu Fragment 1 (der damaligen Instanz) verloren geht und die onTick Methode nicht mehr weiß wohin sie die neue Zahl schicken soll.

Ich hoffe ich habe es verständlich beschrieben.

Hier ist noch der mMn relevante Code

------------------------------------------
ACTIVITY
------------------------------------------

Code:
 /*
    Startet das über den Drawer ausgewählte Fragment
     */
    [B]public void setFragment(int position, Fragment frag)[/B] {
        try {
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            Fragment fragment = frag;
            fragmentTransaction.replace(R.id.frame_container, fragment).commit();
            mLvDrawerMenu.setItemChecked(position, true);
            mDrawerLayout.closeDrawer(mLvDrawerMenu);
            mLvDrawerMenu.invalidateViews();
        } catch (Exception ex) {
            Log.e("setFragment", ex.getMessage());
        }
    }

Code:
  /*
   Startet ein Countdown Objekt um es von "xx" herunter zählen zu lassen
    */
  [B]  public void countdown() [/B]{

        countDownTimer = new CountDownTimer(15000, 1000) {


            public void onTick(long millisUntilFinished) {
                int pass = (int) (millisUntilFinished / 1000);
                fragmentCommunicator.passCountdownValues(pass);
                fragmentCommunicator.setTextColor(1);

            }

            public void onFinish() {
                fragmentCommunicator.passCountdownValues(-1); //Initialwert ist in SpeedFragment definiert
                STATE = 1; // Wenn der Countdown beendet ist, wird der Status auf Laufend gesetzt
                fragmentCommunicator.changeStateIcon(1);
                fragmentCommunicator.setTextColor(0);
            }
        }.start();
    }

Code:
 [B]private void stateHandler(int s)[/B] {

        /*
        Wenn man LÄUFT und schneller als 25 km/h ist, wechselt man zu FAHREN
         */
        if (STATE == 1 && s >= 25) {
            STATE = 2;
            fragmentCommunicator.changeStateIcon(2);
        }

        /*
        Wenn man FÄHRT und die die 25 km/h unterschreitet, welchselt man zu COUNTDOWN.
        Dieser wird daraufhin gestartet
         */
        if (STATE == 2 && s < 25) {
            STATE = 3;
            fragmentCommunicator.changeStateIcon(3);
            countdown();
        }

        /*
        Wenn man im laufenden Countdown ist und die Geschwindigkeit wieder mehr als 25 km/h beträgt,
        wird der Countdown beendet und man befindet sich wieder im Status FAHREN
         */
        if (STATE == 3 && s >= 25) {
            countDownTimer.cancel();
            fragmentCommunicator.passCountdownValues(-1); //reset Wert
            STATE = 2;
            fragmentCommunicator.changeStateIcon(2);
        }


    }


------------------------------------------
FRAGMENT
------------------------------------------

Code:
    /*
Ändert das Bild in der State-Karte (von grau nach schwarz) und erstellt einen Toast
1 = walking, 2 = driving, 3 = countdown
 */
    @Override
   [B] public void changeStateIcon(int state)[/B] {

        switch (state) {

            case 1:

                iv_walking.setImageResource(R.drawable.ic_walking);
                iv_driving.setImageResource(R.drawable.ic_car_grey);
                iv_countdown.setImageResource(R.drawable.ic_sandwatch_grey);
                iv_countdown2.setImageResource(R.drawable.ic_sandwatch_grey);

                STATE = 1;
                txt_countdown.setText(""+STATE);
                break;

            case 2:

                iv_walking.setImageResource(R.drawable.ic_walking_grey);
                iv_driving.setImageResource(R.drawable.ic_car);
                iv_countdown.setImageResource(R.drawable.ic_sandwatch_grey);
                iv_countdown2.setImageResource(R.drawable.ic_sandwatch_grey);

                STATE = 2;
                txt_countdown.setText(""+STATE);
                break;

            case 3:

                iv_walking.setImageResource(R.drawable.ic_walking_grey);
                iv_driving.setImageResource(R.drawable.ic_car_grey);
                iv_countdown.setImageResource(R.drawable.ic_sandwatch);
                iv_countdown2.setImageResource(R.drawable.ic_sandwatch);

                STATE = 3;
                txt_countdown.setText(""+STATE);
                break;
        }

    }

Code:
 @Override
   [B] public void passCountdownValues(int sec)[/B] {

        if (sec != -1)
            txt_countdown.setText("" + sec);
        else txt_countdown.setText("" + COUNTDOWNINITIALVALUE);

    }
 

Anhänge

  • Screenshot_2015-04-27-12-42-54.png
    Screenshot_2015-04-27-12-42-54.png
    24,7 KB · Aufrufe: 195
Zuletzt bearbeitet:
Ich finde 25 kmh zu schnell aber okay
Du könntest sharedpreferences verwenden
 
  • Danke
Reaktionen: Parg
Das mit den 25 kmh hat sich in der Realität tatsächlich als unpraktisch erwiesen und ich habe es ein wenig heruntergeschraubt :)

Dein Tipp mit den SharedPreferences hat mir leider nicht geholfen, aber ich konnte das Problem nun finden, bzw. umgehen.

Da ich Neuling im Thema Fragment bin, waren mir die Funktionen hide/add (die das Fragment nicht aus dem Lifecycle reißen) unbekannt. Nun klappt alles wie geschmiert.

Zwar ist der Code nun aufgebläht, aber besser als eine schlechte Funktionalität

Code:
 /*
    Startet das über den Drawer ausgewählte Fragment
     */
    public void setFragment(int position) {
        try {
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

            if (position == 0) {
                if (speedFrag == null) {
                    speedFrag = new SpeedFragment();
                    fragmentCommunicator = (FragmentCommunicator) speedFrag; // Activity und Fragment per Interface verbinden
                    fragmentTransaction.add(R.id.frame_container, speedFrag).commit();
                    currentlyDisplayedFragment = 0;
                } else {
                    if (currentlyDisplayedFragment != 0) {
                        fragmentTransaction.hide(aboutFrag).show(speedFrag).commit();
                        currentlyDisplayedFragment = 0;
                    }
                }

            } else if (position == 1) {
                if (aboutFrag == null) {
                    aboutFrag = new AboutFragment();
                    fragmentTransaction.hide(speedFrag).add(R.id.frame_container, aboutFrag).commit();
                    currentlyDisplayedFragment = 1;
                }
                if (currentlyDisplayedFragment != 1) {
                    fragmentTransaction.hide(speedFrag).show(aboutFrag).commit();
                    currentlyDisplayedFragment = 1;
                }

            }

            mLvDrawerMenu.setItemChecked(position, true);
            mDrawerLayout.closeDrawer(mLvDrawerMenu);
            mLvDrawerMenu.invalidateViews();
        } catch (Exception ex) {
            Log.e("setFragment", ex.getMessage());
        }
 

Ähnliche Themen

S
Antworten
4
Aufrufe
1.034
Sempervivum
S
R
Antworten
3
Aufrufe
1.676
Ritartet
R
B
Antworten
4
Aufrufe
529
bb321
B
Zurück
Oben Unten