2010-01-31 17 views
7

Ich benutze einen TimePicker unter API 1.5 und wenn die Ausrichtung auf meinem Gerät geändert wird (eine Aktie G1 läuft 1.6 - aber NICHT auf dem 1.5/1.6 Emulator), wird das Stundenfeld leer . Es erinnert sich immer noch an die Stunde, es zeigt es einfach nicht. Gibt es einen Workaround dafür?Android TimePicker Stundenfeld verschwindet nach Orientierungsänderung

Das gleiche Problem wurde hier sonst jemand beschrieben:

http://groups.google.com/group/android-beginners/browse_thread/thread/b4288004021b876/de5899a2bb291ab5

Nichts hilfreich ausblieb - Stackoverflow besser machen können?

+2

Haben Sie jemals eine Antwort darauf erhalten? Ich habe das gleiche Problem. DialogPreference ist die Basisklasse und alle Antworten scheinen davon auszugehen, dass es sich um eine Aktivität handelt. Ich kann sehen, dass ich die Stunde einstelle, aber sie bleibt leer, bis Sie auf + oder - drücken, dann wird der Wert gespeichert. – user405821

+0

Hallo @ user405821, ich fand dieses Verhalten auf meinem Gerät, das GingerBeard ausgeführt wird. Allerdings läuft die gleiche App auf JellyBean-Gerät, ist es nicht passiert. Ich erweitere DialogPreference und verwende TimePicker auf meiner PreferenceActivity (auf JellyBeans, PreferenceFragment). Ich kann dieses Problem noch nicht lösen. –

+0

@ user405821 Ich habe eine Antwort hinzugefügt, die mein Problem gelöst hat und auch deine lösen kann. –

Antwort

0

In onSaveInstanceState() für Ihre Aktivität, erhalten Sie den Stundenwert aus der TimePicker und legen Sie es in die Bundle. In onRestoreInstanceState() für Ihre Aktivität, erhalten Sie die Stunde aus der Bundle und legen Sie sie in die TimePicker.

TimePicker sollte das allein behandeln, aber dies kann das Problem für Sie umgehen.

+0

Danke für den Vorschlag. Leider ändert sich daran nichts. Interessanterweise habe ich, als ich debuggte, um zu sehen, was zu dieser Zeit "change" passiert, gesehen, dass TimePicker (intern) 'onTimeChanged()' aufruft, und der einzige Listener, den ich sehe, ist NO_OP_CHANGE_LISTENER. Ich versuchte auch 'invalidate()' auf dem TimePicker während 'onResume()' zu nennen. Kein Glück. Es ist, als ob es irgendwo eine Einstellung gibt, die angibt, dass die Stunde nicht angezeigt wird; weil es (offensichtlich) neu gezeichnet wird, malt es den Container für die Nummer, es behält den vorhandenen Wert bei; Es zeigt einfach nicht die Nummer. – sosiouxme

6

Verschieben Sie einfach das Aufrufen der Methoden TimePicker.setCurrentHour und TimePicker.setCurrentMinute in die onResume-Methode Ihrer Aktivität.

+5

Das allein war mir nicht genug. Wenn Sie die Stunde auf einen anderen Wert und dann auf den tatsächlichen Wert (in der onResume-Methode) festlegen, wurde das Problem behoben. – Ralf

+1

Dem stimme ich mit Ralf im vorherigen Kommentar zu. Kurz bevor ich den Wert auf den tatsächlichen Wert setze, setze ich ihn auf Null. Die notierte Änderung bewirkt, dass der Wert im Feld entsprechend neu gezeichnet wird. –

+0

Den Wert auf Null und dann auf den realen Wert zu setzen, funktioniert normalerweise für mich, aber nicht, wenn der reale Wert 12:00 Uhr ist. Also setze ich den Wert auf Null, dann auf sechs und dann auf den realen Wert. Es scheint, dass dies in allen Fällen funktioniert. – Cimlman

3

Wie bereits erwähnt, wird das Problem durch Überschreiben der onResume() -Methode behoben.

0

Ich habe eine Tonne Schlaf über diese verloren und habe es gerade herausgefunden. Wenn Sie eine DialogPreference verwenden, müssen Sie die showDialog-Methode überschreiben und Ihre currentHour und currentMinute dort zurücksetzen. Wie folgt aus:

@Override 
protected void showDialog(Bundle state) { 
    super.showDialog(state); 

    mBeginShiftTp.setCurrentHour(mBeginShiftTp.getCurrentHour()); 
    mBeginShiftTp.setCurrentMinute(mBeginShiftTp.getCurrentMinute()); 
    mEndShiftTp.setCurrentHour(mEndShiftTp.getCurrentHour()); 
    mEndShiftTp.setCurrentMinute(mEndShiftTp.getCurrentMinute()); 

}

1

Werfen Sie einen Blick auf diese: http://code.google.com/p/android/issues/detail?id=22824 Egal, was Sie tun, werden Sie nicht in der Lage sein, das Problem zu beheben, ohne die Aktivität zu zerstören und es neu zu erstellen, wenn das Drehen auftritt . Um nicht in eine Endlosschleife zu kommen, überprüfen Sie einfach, ob der savedInstanceState! = Null in onCreate ist. So etwas wie dies funktioniert:

if (savedInstanceState!=null){ 
    Intent myIntent = 
     new Intent(getApplicationContext(), CurrentClassName.class); 
    startActivityForResult(myIntent, 0); 
    finish(); 
} 
0

auf dem Link aus, dass DanRoss vorgesehen ist, wird das Problem im Zusammenhang mit dem Picker nicht die Stunde zu aktualisieren, wenn die Stunde nicht geändert hat. Bei Orientierungsänderungen ist dieses Verhalten fehlerhaft, da die Stunde vor der Rotation immer der Stunde nach der Rotation entspricht.

Für diejenigen, die TimePickerDialog verwenden, ein Weg, um dies ist die Standardimplementierung zu erweitern und es zu zwingen, die Stunde zu aktualisieren, indem Sie die Zeit, die Aktualisierung (Stunde und Minute gleich 0 in meinem Beispiel voran) und dann Update der Stunde um die tatsächliche Stunde zu sein.

Es kann möglich sein, etwas ähnliches nur mit der TimePicker Steuerung zu bauen.

Hier ist ein funktionierendes Beispiel für die TimePickerDialog:

import android.content.Context; 
import android.os.Bundle; 
import android.widget.TimePicker; 

public class TimePickerDialog extends android.app.TimePickerDialog 
{ 
    private final String HOUR_KEY = "Hour"; 
    private final String MINUTE_KEY = "Minute"; 
    private int hourOfDay; 
    private int minute; 

    public TimePickerDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView) 
    { 
     super(context, callBack, hourOfDay, minute, is24HourView); 

     this.hourOfDay = hourOfDay; 
     this.minute = minute; 
    } 

    @Override 
    public void onTimeChanged (TimePicker view, int hourOfDay, int minute) 
    { 
     super.onTimeChanged(view, hourOfDay, minute); 

     this.hourOfDay = hourOfDay; 
     this.minute = minute; 
    } 

    @Override 
    public Bundle onSaveInstanceState() 
    { 
     Bundle savedInstanceState = super.onSaveInstanceState(); 

     if (savedInstanceState == null) 
     { 
      savedInstanceState = new Bundle(); 
     } 

     savedInstanceState.putInt(HOUR_KEY, this.hourOfDay); 
     savedInstanceState.putInt(MINUTE_KEY, minute); 

     return savedInstanceState; 
    } 

    @Override 
    public void onRestoreInstanceState(Bundle savedInstanceState) 
    { 
     super.onRestoreInstanceState(savedInstanceState); 

     // The code for updating the hour is currently not doing anything 
     // if the hour has not changed. 
     // Force it to update by setting it to zero first 
     this.updateTime(0, 0); 

     this.hourOfDay = savedInstanceState.getInt(HOUR_KEY); 
     this.minute = savedInstanceState.getInt(MINUTE_KEY); 

     // Now it will update 
     this.updateTime(this.hourOfDay, this.minute); 
    } 
} 
0

Dieser Fehler auf Android offiziellen Forum Bug 5483 verwandt ist. Nun, und diese Diskussion, sie schlagen eine einfache Lösung vor und es funktioniert für mich. Ich habe das Attribut android:onConfigurationChanges=orientation zu meiner Aktivität unter AndroidManifest.xml hinzugefügt.

Wichtig: Je von Ihnen Aktivität (andere Widgets ...), kann es Nebenwirkungen

0

habe ich weiß, ich bin ein wenig spät, um die Partei, aber da dieses Problem noch, ich existiert fühle, dass es eine wirkliche Antwort verdient.

Von dem, was ich an anderer Stelle gelesen habe, hat das Problem mit den einzelnen Nummernfeldern des TimePicker alle mit genau der gleichen ID zu tun. Der Grund dafür ist, dass, wenn Sie den Bildschirm drehen, Android alle Ihre Dialoge schließt, öffnet alle Ihre Dialoge mit dem typischen onCreateDialog -> onPrepareDialog, und dann, am wichtigsten, , nachdem Sie Ihre Dialoge gemacht haben, geht es zurück und stellt wieder her, was früher da war. Das bedeutet, dass egal was Sie vorher tun, Android wird kommen und brechen Sie Ihre TimePicker.

Die Antwort, obwohl nicht die schönste Option, ist nach Androiden zu kommen und es wieder einzustellen.

Hier ist, wie ich es getan hätte, habe ich einfach meinen eigenen Timepicker gemacht:

public class MyTimePicker extends TimePicker { 

    public MyTimePicker(Context context) { 
     super(context); 
    } 
    public MyTimePicker(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 
    public MyTimePicker(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    private final static String B_MIN = "bMin"; 
    private final static String B_HOUR = "bHour"; 
    private final static String B_SUPER = "bSuper"; 

    // here's the first key, we're going to override how the TimePicker saves 
    // its state 

    @Override 
    public Parcelable onSaveInstanceState() { 
     Bundle bundle = new Bundle(); 
     bundle.putParcelable(B_SUPER, super.onSaveInstanceState()); 
     bundle.putInt(B_MIN, getCurrentMinute()); 
     bundle.putInt(B_HOUR, getCurrentHour()); 
     return bundle; 
    } 

    // this function gets called when we are restoring, but before android 
    // does its thing 

    @Override 
    public void onRestoreInstanceState(Parcelable state) { 
     if (state instanceof Bundle) { 
      final Bundle bundle = (Bundle) state; 
      super.onRestoreInstanceState(bundle.getParcelable(B_SUPER)); 

      // here it is, not the prettiest option, but it gets the job done 
      // we simply wait 0.1 sec and then update the TimePicker 
      // since all of this happens in the same thread, its guarenteed to 
      // be after the android reset 

      // also, this handler gets the HandlerLeak warning, I don't 
      // think this can leak though seeing as it's only called once 
      // with a 100 ms delay 

      (new Handler() { 
       @Override 
       public void handleMessage(Message msg) { 

        setCurrentMinute(bundle.getInt(B_MIN)); 
        setCurrentHour(bundle.getInt(B_HOUR)); 
       } 
      }).sendEmptyMessageDelayed(0, 100); 

      return; 
     } 
     super.onRestoreInstanceState(state); 
    } 
}  

Und ja, der Handler ist erforderlich. Wenn Sie einfach die setCurrent-Befehle von onRestoreInstanceState ausführen, überschreibt Android Sie einfach.

0

Ich sehe dieses Problem war früher, aber ich löste Problem und wenn jemand dieses Problem hat, ist dies zu lösen: Alles in onResume() tun, erst Wert für Stunde, dann Stunden auf timePicker zu Stunde + 1 und dann auf Stunde eingestellt. Das funktioniert für mich.

0

verrückte Lösung, die funktioniert:

  • Run AsynTask in onResume()
  • Schlaf für 50 ms
  • Wechseln Sie wieder zu UI-Thread, mit Activity.runOnUiThread()
  • In UI-Thread gesetzt min/Stunde auf 0
  • Dann Satz min/Stunde auf Ihre Werte

Hier ist ein Kern mit dem Code, fertig zum Kopieren-Einfügen :)
https://gist.github.com/sorrro/9415702

Verwandte Themen