2010-04-05 78 views
36

我可以控制Android TimePicker視圖,只顯示分鐘到15分鐘的時間間隔嗎?Android - TimePicker分鐘到15

如果現在是12:28,顯示12:30並且點擊+和 - 按鈕將遞增和遞減15?

謝謝

三通

回答

3

你必須寫自己的TimePicker。不確定您是否可以擴展現有的TimePicker並自行處理按鈕事件。

3

我想我想通了。可能是貧民窟的方式,但...

這是我做的。

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

以下爲我工作。

首先,在的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); 
} 
+0

我才發現我的邏輯存在問題確定分鐘值。使用上面的代碼,「+」按鈕不起作用。當我修復它時,我會發布更新後的代碼。 – 2010-06-24 05:12:54

+0

如果修復了[此錯誤](http://code.google.com/p/android/issues/detail?id=27653),我們可以刪除一些難看的代碼。 – user250343 2012-04-06 21:43:48

1

首先我」 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方法取代有幫助的,除了這一切都是相同的。

3
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的代碼相同。

19

這裏是我的版本,在這裏你可以設置時間間隔:

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

    } 
}; 
+3

但這段代碼不會設置時間選擇器的值的上限和下限 – ANinJa 2015-10-08 12:27:32

+1

這是不是高於棒棒糖,你能給這個替代解決方案嗎? – 2016-05-15 05:45:58

+0

Ankit Thakkar是對的。更確切地說,這是特別的時鐘佈局是有問題的。這是由於minutePicker爲空。 我還沒有找到如何解決這個問題。 – PAD 2016-05-24 10:36:17

18

創建一個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(); 
      } 
    } 
} 
+0

在45和00之間移動時,小時不會發生變化。僅在兩次重複之後,我纔會更改... – schabluk 2014-09-27 13:49:31

+1

@schabluk您是對的。這是一個錯誤。其實我分了兩分鐘。如果不這樣做,它不能自動滾動分鐘。我會嘗試修復它,並更新我的答案,因爲我得到修復。 – Ali 2014-09-29 05:41:39

+1

我希望我能夠把這個解決方案,但Android Studio中抱怨'ClassNotFoundException'對'的Class.forName(「com.android.internal.R的$ id」)'即使已經的android.jar在外部庫存在。 – CallMeLaNN 2014-10-29 15:03:40

2

我已經想出了一個解決方案,基於對這個問題的一些以前的答案,和我自己的一些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()); 
     } 
    }; 
} 
+0

AttributeSet attrs當我想使用您的代碼時,attrs參數是什麼?請告訴我任何解決方案如何使用此 – Asmi 2016-08-22 10:46:52

+0

使用你的代碼它接受15分鐘的差異,但沒有顯示timepicker 15分鐘值..如何使用attributeset這裏.. plz解釋.. – Asmi 2016-08-22 11:32:47

+0

我需要你的幫助,使用你的代碼幫助我如果你可以的話.. – Asmi 2016-08-22 12:16:39

0

這是我寫的版本。這是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>