我可以控制Android TimePicker視圖,只顯示分鐘到15分鐘的時間間隔嗎?Android - TimePicker分鐘到15
如果現在是12:28,顯示12:30並且點擊+和 - 按鈕將遞增和遞減15?
謝謝
三通
我可以控制Android TimePicker視圖,只顯示分鐘到15分鐘的時間間隔嗎?Android - TimePicker分鐘到15
如果現在是12:28,顯示12:30並且點擊+和 - 按鈕將遞增和遞減15?
謝謝
三通
你必須寫自己的TimePicker。不確定您是否可以擴展現有的TimePicker並自行處理按鈕事件。
我想我想通了。可能是貧民窟的方式,但...
這是我做的。
start_time.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
updateDisplay(hourOfDay, minute);
}
});
private void updateDisplay(int hourOfDay, int minute) {
// do calculation of next time
// nextTime = calculation of next time;
// the processed boolean is to prevent infinite loop
if (!processed) {
start_time.setCurrentMinute(nextTime);
processed = true;
} else {
processed = false;
}
}
以下爲我工作。
首先,在的onCreate:
pickStartTime = (TimePicker)findViewById(R.id.StartTime);
pickStartTime.setOnTimeChangedListener(mStartTimeChangedListener);
設置OnTimeChangedListener:
private TimePicker.OnTimeChangedListener mStartTimeChangedListener =
new TimePicker.OnTimeChangedListener() {
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
updateDisplay(view, startDate, hourOfDay, minute);
}
};
空OnTimeChangedListener(在評論中updateDisplay說明如下):
private TimePicker.OnTimeChangedListener mNullTimeChangedListener =
new TimePicker.OnTimeChangedListener() {
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
}
};
private void updateDisplay(TimePicker timePicker, Date date, int hourOfDay, int minute) {
// do calculation of next time
int nextMinute = 0;
if (minute >= 45 && minute <= 59)
nextMinute = 45;
else if(minute >= 30)
nextMinute = 30;
else if(minute >= 15)
nextMinute = 15;
else if(minute > 0)
nextMinute = 0;
else {
nextMinute = 45;
}
// remove ontimechangedlistener to prevent stackoverflow/infinite loop
timePicker.setOnTimeChangedListener(mNullTimeChangedListener);
// set minute
timePicker.setCurrentMinute(nextMinute);
// hook up ontimechangedlistener again
timePicker.setOnTimeChangedListener(mStartTimeChangedListener);
// update the date variable for use elsewhere in code
date.setMinutes(nextMinute);
}
首先我」 D喜歡感謝安德魯克服stackoverflow錯誤(無限循環)。我的邏輯來增加時間b y 15分鐘是這樣的.Declare int previousMinuteSet = 0作爲給定類中的成員變量。
// remove ontimechangedlistener to prevent stackoverflow/infinite loop timePicker.setOnTimeChangedListener(mNullTimeChangedListener);
if((minute - previousMinuteSet == 1) || (minute - previousMinuteSet == 15) || (minute - previousMinuteSet == -45)) {
// set hour
timePicker.setCurrentHour((hourOfDay + minute/45) % 12);
// set minute
timePicker.setCurrentMinute((minute + 14) % 60);
} else {
// set hour
timePicker.setCurrentHour(hourOfDay);
// set minute
timePicker.setCurrentMinute(minute);
}
previousMinuteSet = minute;
// hook up ontimechangedlistener again
timePicker.setOnTimeChangedListener(timePickerChangedListener);
希望,這可能將是others.The代碼我在安德魯的updateDisplay方法取代有幫助的,除了這一切都是相同的。
private void updateDisplay(TimePicker timePicker, int hourOfDay, int minute) {
int nextMinute = 0;
timePicker.setOnTimeChangedListener(mNullTimeChangedListener);
if (minute >= 45 && minute <= 59)
nextMinute = 45;
else if (minute >= 30)
nextMinute = 30;
else if (minute >= 15)
nextMinute = 15;
else if (minute > 0)
nextMinute = 0;
else {
nextMinute = 45;
}
if (minute - nextMinute == 1) {
if (minute >= 45 && minute <= 59)
nextMinute = 00;
else if(minute >= 30)
nextMinute = 45;
else if(minute >= 15)
nextMinute = 30;
else if(minute > 0)
nextMinute = 15;
else {
nextMinute = 15;
}
}
timePicker.setCurrentMinute(nextMinute);
timePicker.setOnTimeChangedListener(timePickerChangedListener);
}
修改+和 - 按鈕的更新顯示方法。其餘的代碼與Andrew Dyer的代碼相同。
這裏是我的版本,在這裏你可以設置時間間隔:
private static final int TIME_PICKER_INTERVAL=15;
private boolean mIgnoreEvent=false;
private TimePicker.OnTimeChangedListener mTimePickerListener=new TimePicker.OnTimeChangedListener(){
public void onTimeChanged(TimePicker timePicker, int hourOfDay, int minute){
if (mIgnoreEvent)
return;
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;
mIgnoreEvent=true;
timePicker.setCurrentMinute(minute);
mIgnoreEvent=false;
}
}
};
創建一個XML文件,並將其命名爲activity_time_picker.xml
現在創建活動課這樣
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.NumberPicker;
import android.widget.TimePicker;
public class TimePickerActivity extends Activity {
TimePicker timePicker;
private int TIME_PICKER_INTERVAL = 15;
NumberPicker minutePicker;
List<String> displayedValues;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.activity_time_picker);
super.onCreate(savedInstanceState);
timePicker = (TimePicker)findViewById(R.id.timePicker1);
timePicker.setIs24HourView(true);
timePicker.setCurrentHour(0);
timePicker.setCurrentMinute(0);
setTimePickerInterval(timePicker);
}
@SuppressLint("NewApi")
private void setTimePickerInterval(TimePicker timePicker) {
try {
Class<?> classForid = Class.forName("com.android.internal.R$id");
// Field timePickerField = classForid.getField("timePicker");
Field field = classForid.getField("minute");
minutePicker = (NumberPicker) timePicker
.findViewById(field.getInt(null));
minutePicker.setMinValue(0);
minutePicker.setMaxValue(3);
displayedValues = new ArrayList<String>();
for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
displayedValues.add(String.format("%02d", i));
}
// for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
// displayedValues.add(String.format("%02d", i));
// }
minutePicker.setDisplayedValues(displayedValues
.toArray(new String[0]));
minutePicker.setWrapSelectorWheel(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
在45和00之間移動時,小時不會發生變化。僅在兩次重複之後,我纔會更改... – schabluk 2014-09-27 13:49:31
@schabluk您是對的。這是一個錯誤。其實我分了兩分鐘。如果不這樣做,它不能自動滾動分鐘。我會嘗試修復它,並更新我的答案,因爲我得到修復。 – Ali 2014-09-29 05:41:39
我希望我能夠把這個解決方案,但Android Studio中抱怨'ClassNotFoundException'對'的Class.forName(「com.android.internal.R的$ id」)'即使已經的android.jar在外部庫存在。 – CallMeLaNN 2014-10-29 15:03:40
我已經想出了一個解決方案,基於對這個問題的一些以前的答案,和我自己的一些dditions。這個解決方案明顯地覆蓋了getCurrentMinute和setCurrentMinute,默認情況下,它會返回分鐘索引,而不是分鐘值(例如,如果您的分鐘間隔爲15,並且選擇器顯示的分鐘數爲30,則在沒有此代碼的情況下返回2)。
此解決方案也會翻轉大於最大間隔值的分鐘數(如果間隔爲15,則任何分鐘> 45將將分鐘值設置爲0並遞增小時值)。
注意:此測試和Android 4.4及5.0的工作。
public class CustomIntervalTimePicker extends TimePicker {
private static final int TIME_PICKER_MINUTE_INTERVAL = 15;
private OnTimeChangedListener timeChangedListener;
public CustomIntervalTimePicker(Context context, AttributeSet attrs) {
super(context, attrs);
try {
Class<?> classForId = Class.forName("com.android.internal.R$id");
Field field = classForId.getField("minute");
NumberPicker minuteSpinner = (NumberPicker) this.findViewById(field.getInt(null));
minuteSpinner.setMaxValue((60/TIME_PICKER_MINUTE_INTERVAL) - 1);
List<String> displayedValues = new ArrayList<>();
for (int i = 0; i < 60; i += TIME_PICKER_MINUTE_INTERVAL)
displayedValues.add(String.format("%02d", i));
minuteSpinner.setDisplayedValues(displayedValues.toArray(new String[displayedValues.size()]));
} catch (Exception e) {
e.printStackTrace();
}
}
private int maxMinuteIndex() {
return (60/TIME_PICKER_MINUTE_INTERVAL) - 1;
}
@Override
public void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener) {
super.setOnTimeChangedListener(internalTimeChangedListener);
this.timeChangedListener = onTimeChangedListener;
}
@Override
public Integer getCurrentMinute() {
return super.getCurrentMinute() * TIME_PICKER_MINUTE_INTERVAL;
}
@Override
public void setCurrentMinute(Integer currentMinute) {
int cleanMinute = currentMinute/TIME_PICKER_MINUTE_INTERVAL;
if(currentMinute % TIME_PICKER_MINUTE_INTERVAL > 0) {
if(cleanMinute == maxMinuteIndex()) {
cleanMinute = 0;
setCurrentHour(getCurrentHour()+1);
} else {
cleanMinute++;
}
}
super.setCurrentMinute(cleanMinute);
}
// We want to proxy all the calls to our member variable OnTimeChangedListener with our own
// internal listener in order to make sure our overridden getCurrentMinute is called. Without
// this some versions of android return the underlying minute index.
private OnTimeChangedListener internalTimeChangedListener = new OnTimeChangedListener() {
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
timeChangedListener.onTimeChanged(view, getCurrentHour(), getCurrentMinute());
}
};
}
這是我寫的版本。這是C#代碼,因爲我使用的是Xamarin,但是我希望任何人都可以將它翻譯成Java,而不是對我來說更難,因爲我需要複製一段Java代碼時執行vica versa翻譯。
這是一個從標準TimePicker有點不同,它的頂部和底部邊框是不連續的,但它是一個缺陷有人會覺得微不足道。
我可以做在使設置自定義間隔幾分鐘更容易,而不是讓你硬編碼在實施間隔值一個更好的工作,但我相信,如果你想很快就可以擦亮這個解決方案!
HourPickerMapper.cs
public class HourPickerMapper
{
public HourPickerMapper() { }
public int MapValue(int hour)
{
return hour;
}
public int MapNumber(int number)
{
return number;
}
public void InitNumberPicker(NumberPicker numberPicker)
{
int[] numbers = new int[24];
for (var i = 0; i < numbers.Length; i++)
{
numbers[i] = i;
}
var displayed = numbers.Select(_ => $"{_:00}").ToArray();
numberPicker.SetDisplayedValues(displayed);
numberPicker.MinValue = 0;
numberPicker.MaxValue = displayed.Length - 1;
}
}
MinutePickerMapper.cs
public class MinutePickerMapper
{
public MinutePickerMapper() { }
public int MapValue(int value)
{
return (int)Math.Floor(value/10.0);
}
public int MapNumber(int number)
{
return number * 10;
}
public void InitNumberPicker(NumberPicker numberPicker)
{
int[] numbers = new int[6];
for (var i = 0; i < numbers.Length; i++)
{
numbers[i] = i * 10;
}
var displayed = numbers.Select(_ => _.ToString()).ToArray();
numberPicker.SetDisplayedValues(displayed);
numberPicker.MinValue = 0;
numberPicker.MaxValue = displayed.Length - 1;
}
}
下面是使用的例子,一個DialogFragment
public class CustomDateTimePickerDialogFragment : Android.Support.V4.App.DialogFragment
{
private DateTime _dt;
private NumberPicker _datePicker, _hourPicker, _minutePicker;
private DatePickerMapper _datePickerMapper;
private HourPickerMapper _hourPickerMapper;
private MinutePickerMapper _minutePickerMapper;
public event EventHandler<DateTimeSetEventArgs> DateTimeSetEvent;
public CustomDateTimePickerDialogFragment()
{
_dt = DateTime.Now + new TimeSpan(24, 0, 0); // now + 1 day
}
public CustomDateTimePickerDialogFragment(DateTime dt)
{
_dt = dt;
if (dt == null)
{
_dt = DateTime.Now + new TimeSpan(24, 0, 0); // now + 1 day
}
}
public override Dialog OnCreateDialog(Bundle savedInstanceState)
{
AlertDialog.Builder builder = new AlertDialog.Builder(Context);
builder.SetNeutralButton(Resource.String.dialog_datetime_now, (sender, e) =>
{
var eventArgs = new DateTimeSetEventArgs();
DateTimeSetEvent.Invoke(this, eventArgs);
});
builder.SetPositiveButton(Resource.String.dialog_ok, (sender, e) =>
{
var hour = _hourPickerMapper.MapNumber(_hourPicker.Value);
var minute = _minutePickerMapper.MapNumber(_minutePicker.Value);
var date = _datePickerMapper.MapNumber(_datePicker.Value);
var eventArgs = new DateTimeSetEventArgs(new DateTime(date.Year, date.Month, date.Day, hour, minute, 0));
DateTimeSetEvent.Invoke(this, eventArgs);
Dismiss();
});
var dialog = builder.Create();
dialog.SetView(createDateTimeView(dialog.LayoutInflater));
_datePicker.Value = _datePickerMapper.MapValue(_dt);
_hourPicker.Value = _hourPickerMapper.MapValue(_dt.Hour);
_minutePicker.Value = _minutePickerMapper.MapValue(_dt.Minute);
return dialog;
}
private View createDateTimeView(LayoutInflater inflater)
{
View view = inflater.Inflate(Resource.Layout.dialog_custom_datetime_picker, null);
_datePicker = view.FindViewById<NumberPicker>(Resource.Id.datePicker);
_datePickerMapper = new DatePickerMapper(DateTime.Now, 10);
_datePickerMapper.InitNumberPicker(_datePicker);
var now = DateTime.Now;
_datePicker.Value = _datePickerMapper.MapValue(now);
_minutePicker = view.FindViewById<NumberPicker>(Resource.Id.minutePicker);
_minutePickerMapper = new MinutePickerMapper();
_minutePickerMapper.InitNumberPicker(_minutePicker);
_minutePicker.Value = _minutePickerMapper.MapValue(now.Minute);
_hourPicker = view.FindViewById<NumberPicker>(Resource.Id.hourPicker);
_hourPickerMapper = new HourPickerMapper();
_hourPickerMapper.InitNumberPicker(_hourPicker);
_hourPicker.Value = _hourPickerMapper.MapValue(now.Hour);
return view;
}
public class DateTimeSetEventArgs : EventArgs
{
public DateTimeSetEventArgs(DateTime dt)
{
IsNow = false;
DT = dt;
}
public DateTimeSetEventArgs()
{
IsNow = true;
}
public DateTime DT { get; }
public bool IsNow { get; }
}
}
dialog_custom_datetime_picker.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/dialog_padding"
>
<!-- Layout for the DatePicker -->
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
>
<NumberPicker
android:id="@+id/datePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" "
/>
<NumberPicker
android:id="@+id/hourPicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=":"
/>
<NumberPicker
android:id="@+id/minutePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
我才發現我的邏輯存在問題確定分鐘值。使用上面的代碼,「+」按鈕不起作用。當我修復它時,我會發布更新後的代碼。 – 2010-06-24 05:12:54
如果修復了[此錯誤](http://code.google.com/p/android/issues/detail?id=27653),我們可以刪除一些難看的代碼。 – user250343 2012-04-06 21:43:48