方向更改后Android TimePicker小时字段消失

时间:2010-01-31 03:53:49

标签: android

我在API 1.5下使用TimePicker,当我的设备上更改了方向(运行1.6的库存G1 - 虽然不在1.5 / 1.6仿真器上)时,小时字段变为空白。它仍然记得小时,它只是没有显示它。有没有解决方法呢?

这里的其他人描述了同样的问题:

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

没有任何帮助即将到来 - StackOverflow可以做得更好吗?

10 个答案:

答案 0 :(得分:6)

只需将TimePicker.setCurrentHour和TimePicker.setCurrentMinute方法的调用移动到Activity的onResume方法。

答案 1 :(得分:3)

如上所述,覆盖onResume()方法将对此问题进行排序。

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

        TimePicker tmp = (TimePicker) this.findViewById(R.id.yourTimePicker);
        tmp.setCurrentHour(7); // This will also set on rotate

    }

答案 2 :(得分:1)

看看这个: http://code.google.com/p/android/issues/detail?id=22824 无论你做什么,如果不破坏Activity并在旋转发生时重新创建它,你将无法解决问题。为了不进入无限循环,请简单检查onCreate中是否存在savedInstanceState!= null。这样的事情会起作用:

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

答案 3 :(得分:0)

onSaveInstanceState()的活动中,从TimePicker中获取小时值并将其放入Bundle。在onRestoreInstanceState()为您的活动,从Bundle获取小时并将其放入TimePicker

TimePicker应该自行处理,但这可能会解决您的问题。

答案 4 :(得分:0)

我已经失去了大量的睡眠,只是弄明白了。当您使用DialogPreference时,您需要覆盖showDialog方法并在那里重置currentHour和currentMinute。像这样:

@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());

}

答案 5 :(得分:0)

根据DanRoss提供的链接,问题与选择器在小时未更改时不更新小时有关。关于方向更改,此行为有问题,因为旋转前的小时始终等于旋转后的小时。

对于那些使用TimePickerDialog的人来说,解决这个问题的方法是扩展默认实现并强制它通过更新时间来更新小时(在我的示例中将小时和分钟设置为等于0)和然后将小时更新为实际小时。

可以仅使用TimePicker控件构建类似的东西。

以下是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);
    }
}

答案 6 :(得分:0)

此错误与Android官方论坛Bug 5483有关。好吧,那个讨论,他们建议一个简单的解决方案,它适用于我。我在android:onConfigurationChanges=orientation上的活动中添加了属性AndroidManifest.xml

重要提示:根据您的活动(其他小工具......),它可能会产生副作用

答案 7 :(得分:0)

我意识到我在聚会上有点迟到,但看到这个问题仍然存在,我觉得它值得一个真正的答案。

从我在其他地方读到的内容,问题与TimePicker的各个数字字段有关,所有字段都具有完全相同的ID。这是一个问题的原因是因为当您旋转屏幕时,android会关闭所有对话框,使用典型的onCreateDialog重新打开所有对话框 - > onPrepareDialog,然后,最重要的是,在你完成对话后,它会重新恢复原来的状态。这意味着无论你事先做了什么,android都会进来并打破你的TimePicker。

答案虽然不是最漂亮的选择,但是在android之后进入并重新设置它。

我是这样做的,我只是制作了自己的TimePicker:

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);
    }
}    

是的,处理程序是必要的。如果你只是从onRestoreInstanceState运行setCurrent命令,android就会覆盖你。

答案 8 :(得分:0)

我发现这个问题很早就开始了,但我解决了问题,如果有人遇到这个问题,这就解决了: 在onResume()中执行的所有操作,首先获取小时值,然后将timePicker上的小时设置为小时+ 1,然后设置为小时。这对我有用。

答案 9 :(得分:0)

有效的疯狂解决方案:

  • 在onResume()
  • 中运行AsynTask
  • 睡眠50毫秒
  • 使用Activity.runOnUiThread()
  • 切换回UI线程
  • 在UI线程中将min / hour设置为0
  • 然后将min / hour设置为您的值

这是代码的要点,准备复制粘贴:)
https://gist.github.com/sorrro/9415702