如何在Android中的TimePickerDialog中设置自定义分钟间隔

jbl*_*nco 6 java android intervals timepicker

我有一个TimePickerDialog工作设置时间,设置为TextView以显示它.现在,我需要帮助将TimePicker(在TimePickerDialog内)的minutues间隔设置为15分钟.我已经看到有一个与TimePicker相关的15分钟间隔问题的帖子,但我不知道如何将它应用于TimePickerDialog,因为我不知道如何使用它在TimePickerDialog中创建的TimePicker.我是Android的新手,完全迷失在这件事上.提前致谢.

Dav*_*ara 14

使用的组合从@Rizwan和这个其他线程,我想出了一个综合的解决方案,允许任意分钟为单位的TimePickerDialog.主要问题是大多数功能都是由android TimePickerDialogTimePicker类隐藏的,而且看起来并不像

  1. 扩展TimePickerDialog以便我们更轻松地访问
  2. 使用反射到达显示器内部并访​​问所需的位(见下文)
  3. 重新连接分钟'NumberPicker'以显示我们的值
  4. 重新TimePicker接收接收和返回值,以NumberPicker表彰我们的自定义增量.
  5. 阻止onStop(),以便它不会在关闭时重置值.

警告

到达UI内部的主要问题是元素由可能发生变化的id引用,甚至id的名称也不能保证永远相同.话虽如此,这是一个有效,稳定的解决方案,并且可能在可预见的未来发挥作用.在我看来,空的catch块应该警告UI已经改变并且应该回退到默认(增量1分钟)行为.

    private class DurationTimePickDialog extends TimePickerDialog
    {
        final OnTimeSetListener mCallback;
        TimePicker mTimePicker;
        final int increment;

        public DurationTimePickDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView, int increment)
        {
            super(context, callBack, hourOfDay, minute/increment, is24HourView);
            this.mCallback = callBack;
            this.increment = increment;
        }

        @Override
        public void onClick(DialogInterface dialog, int which) {
                if (mCallback != null && mTimePicker!=null) {
                    mTimePicker.clearFocus();
                    mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
                            mTimePicker.getCurrentMinute()*increment);
                }
        }

        @Override
        protected void onStop()
        {
            // override and do nothing
        }

        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            try
            {
                Class<?> rClass = Class.forName("com.android.internal.R$id");
                Field timePicker = rClass.getField("timePicker");
                this.mTimePicker = (TimePicker)findViewById(timePicker.getInt(null));
                Field m = rClass.getField("minute");

                NumberPicker mMinuteSpinner = (NumberPicker)mTimePicker.findViewById(m.getInt(null));
                mMinuteSpinner.setMinValue(0);
                mMinuteSpinner.setMaxValue((60/increment)-1);
                List<String> displayedValues = new ArrayList<String>();
                for(int i=0;i<60;i+=increment)
                {
                    displayedValues.add(String.format("%02d", i));
                }
                mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

构造函数接受增量值并保留其他一些引用.请注意,这省略了错误检查,我们更喜欢60%increment==0

onCreate使用UI字段和反射的名称来发现当前位置.这再次省略了错误检查,应该是"故障安全",即如果出现问题则恢复默认行为.

onClick重写以将正确的分钟值返回给回调侦听器

重写onStop以防止在对话框关闭时第二次返回(不正确的)索引值.继续,亲自尝试一下.

其中大部分来自于挖掘TimePickerDialog源代码.

  • 好的,我设法通过添加onTimeChanged检查以及最后一次保存小时和分钟来解决30分钟的间隔.如果两者不同,则只使用`view.setCurrentHour(lastSavedHour)`来改变分钟而不是两者.但我不确定这是否是一个很好的方法...但如果有更好的解决方案,请随时让我知道:) (2认同)
  • 这在 android 5 中似乎不起作用: Field m = rClass.getField("minute"); NumberPicker mMinuteSpinner = (NumberPicker)mTimePicker.findViewById(m.getInt(null)); 没有找到视图 (2认同)

Riz*_*aib 11

如果您使用时间选择器而不是时间选择器对话框那么这很好.但实际上有一个解决方案..这是我用来满足相同要求的..我使用CustomTimePickerDialog.每件事都是一样的,只有TimePickerDialog会在代码中更改为CustomTimePickerDialog.

CustomTimePickerDialog timePickerDialog = new CustomTimePickerDialog(myActivity.this, timeSetListener, 
            Calendar.getInstance().get(Calendar.HOUR), 
            CustomTimePickerDialog.getRoundedMinute(Calendar.getInstance().get(Calendar.MINUTE) + CustomTimePickerDialog.TIME_PICKER_INTERVAL), 
            false
);
timePickerDialog.setTitle("2. Select Time");
timePickerDialog.show();
Run Code Online (Sandbox Code Playgroud)

这是我的CustomTimePickerDialog类...只需在项目中使用此类并将TimePickerDialog更改为CustomTimePickerDialog ..

public class CustomTimePickerDialog extends TimePickerDialog{

    public static final int TIME_PICKER_INTERVAL=10;
    private boolean mIgnoreEvent=false;

    public CustomTimePickerDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute,
        boolean is24HourView) {
    super(context, callBack, hourOfDay, minute, is24HourView);
    }
/*
 * (non-Javadoc)
 * @see android.app.TimePickerDialog#onTimeChanged(android.widget.TimePicker, int, int)
 * Implements Time Change Interval
 */
    @Override
    public void onTimeChanged(TimePicker timePicker, int hourOfDay, int minute) {
        super.onTimeChanged(timePicker, hourOfDay, minute);
        this.setTitle("2. Select Time");
        if (!mIgnoreEvent){
            minute = getRoundedMinute(minute);
            mIgnoreEvent=true;
            timePicker.setCurrentMinute(minute);
            mIgnoreEvent=false;
        }
    }

    public static int getRoundedMinute(int minute){
         if(minute % TIME_PICKER_INTERVAL != 0){
            int minuteFloor = minute - (minute % TIME_PICKER_INTERVAL);
            minute = minuteFloor + (minute == minuteFloor + 1 ? TIME_PICKER_INTERVAL : 0);
            if (minute == 60)  minute=0;
         }

        return minute;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用此CustomTimePickerDialog类之后,您需要做的就是在代码中使用CustomTimePickerDialog而不是TimePickerDialog来访问/覆盖TimePickerDialog类的默认函数.简单来说,我的意思是你的timeSetListener将在此之后如下......

private CustomTimePickerDialog.OnTimeSetListener timeSetListener = new CustomTimePickerDialog.OnTimeSetListener() {
    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {

    }
}// using CustomTimePickerDialog
Run Code Online (Sandbox Code Playgroud)

  • 谢谢@Rizwan.例如,该解决方案可以成功地将可选择的时间约束为15分钟的增量.但是,显示在当前分钟值上方和下方的相邻分钟值仍然是一分钟增量,而不是15分钟增量.例如,选定的分钟值30在一侧有29个而在另一侧有31个,而不是一侧有15个而另一侧有45个.这会导致用户体验有点分散注意力.如果相邻值也以15分钟为增量,则解决方案会更好.你有解决方案吗? (5认同)

njz*_*zk2 1

您可以使用常规 AlertDialog 并使用 setView 来包含自定义 TimePicker 视图。