2014-11-14 35 views
16

Tôi gặp sự cố với tiện ích TimePicker trên API 21. Cho đến API 19, TimePicker là một danh sách up-down như iOS, nhưng trong 21+ nó tròn, giống như trong ứng dụng lịch.API Android 21 - Tiện ích con TimePicker

Làm cách nào tôi có thể sử dụng hình ảnh cũ trong 21+, vì nó phá vỡ thiết kế của tôi, nếu đó là tiện ích mới.

+0

Tôi khuyên bạn nên liên kết stackoverflow này cho câu trả lời có lập trình và XML: http://stackoverflow.com/questions/24449723/is-it-possible-to-change-the-style-of-an-android- l-timepickerdialog – Zhang

Trả lời

39

Bạn có thể chỉ định bộ chọn thời gian kiểu spinner bằng cách đặt thuộc tính timePickerMode thành "spinner". Giá trị mặc định trên Material là "clock".

<TimePicker 
    ... 
    android:timePickerMode="spinner" /> 
+3

Điều này sẽ được thực hiện theo cách lập trình như thế nào? –

+1

Bạn có thể chuyển một defStyleAttr hoặc defStyleRes trong khi tạo bộ chọn thời gian. – alanv

+0

Có thể sử dụng trình theo dõi thời gian API 21 mới này trên Lollipop trước không? – fpopic

0

Bạn có thể sử dụng chế độ spinner theo cách có sử dụng lớp tùy chỉnh. Đối với các phiên bản trước đó Từ lolipop nó sẽ thay đổi chế độ timepicker từ đồng hồ thành spinner và nó cũng cho phép bạn thiết lập việc chọn thời gian sau một thời gian cụ thể (sử dụng setmax() & setmin()). Trong đoạn code dưới đây tôi đã sử dụng set max() để giới hạn thời gian tối đa.

public class RangeTimePickerDialog extends TimePickerDialog { 

    private int minHour = -1; 
    private int minMinute = -1; 

    private int maxHour = 25; 
    private int maxMinute = 25; 

    private int currentHour = 0; 
    private int currentMinute = 0; 

    private Calendar calendar = Calendar.getInstance(); 
    private DateFormat dateFormat; 


    public RangeTimePickerDialog(Context context, int dialogTheme, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView) { 
     super(context, callBack, hourOfDay, minute, is24HourView); 
     currentHour = hourOfDay; 
     currentMinute = minute; 
     dateFormat = DateFormat.getTimeInstance(DateFormat.SHORT); 
     fixSpinner(context, hourOfDay, minute, is24HourView); 

     try { 
      Class<?> superclass = getClass().getSuperclass(); 
      Field mTimePickerField = superclass.getDeclaredField("mTimePicker"); 
      mTimePickerField.setAccessible(true); 
      TimePicker mTimePicker = (TimePicker) mTimePickerField.get(this); 
      mTimePicker.setOnTimeChangedListener(this); 
     } catch (NoSuchFieldException e) { 
     } catch (IllegalArgumentException e) { 
     } catch (IllegalAccessException e) { 
     } 
    } 

    public void setMin(int hour, int minute) { 
     minHour = hour; 
     minMinute = minute; 
    } 

    public void setMax(int hour, int minute) { 
     maxHour = hour; 
     maxMinute = minute; 
    } 

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

     boolean validTime = true; 
     if (hourOfDay < minHour || (hourOfDay == minHour && minute < minMinute)){ 
      validTime = false; 
     } 

     if (hourOfDay > maxHour || (hourOfDay == maxHour && minute > maxMinute)){ 
      validTime = false; 
     } 

     if (validTime) { 
      currentHour = hourOfDay; 
      currentMinute = minute; 
     } 

     updateTime(currentHour, currentMinute); 
     updateDialogTitle(view, currentHour, currentMinute); 
    } 

    private void updateDialogTitle(TimePicker timePicker, int hourOfDay, int minute) { 
     calendar.set(Calendar.HOUR_OF_DAY, hourOfDay); 
     calendar.set(Calendar.MINUTE, minute); 
     String title = dateFormat.format(calendar.getTime()); 
     setTitle(title); 
    } 


    private void fixSpinner(Context context, int hourOfDay, int minute, boolean is24HourView) { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // android:timePickerMode spinner and clock began in Lollipop 
      try { 
       // Get the theme's android:timePickerMode 
       //two modes are available clock mode and spinner mode ... selecting spinner mode for latest versions 
       final int MODE_SPINNER = 2; 
       Class<?> styleableClass = Class.forName("com.android.internal.R$styleable"); 
       Field timePickerStyleableField = styleableClass.getField("TimePicker"); 
       int[] timePickerStyleable = (int[]) timePickerStyleableField.get(null); 
       final TypedArray a = context.obtainStyledAttributes(null, timePickerStyleable, android.R.attr.timePickerStyle, 0); 
       Field timePickerModeStyleableField = styleableClass.getField("TimePicker_timePickerMode"); 
       int timePickerModeStyleable = timePickerModeStyleableField.getInt(null); 
       final int mode = a.getInt(timePickerModeStyleable, MODE_SPINNER); 
       a.recycle(); 
       if (mode == MODE_SPINNER) { 
        TimePicker timePicker = (TimePicker) findField(TimePickerDialog.class, TimePicker.class, "mTimePicker").get(this); 
        Class<?> delegateClass = Class.forName("android.widget.TimePicker$TimePickerDelegate"); 
        Field delegateField = findField(TimePicker.class, delegateClass, "mDelegate"); 
        Object delegate = delegateField.get(timePicker); 
        Class<?> spinnerDelegateClass; 
        if (Build.VERSION.SDK_INT != Build.VERSION_CODES.LOLLIPOP) { 
         spinnerDelegateClass = Class.forName("android.widget.TimePickerSpinnerDelegate"); 
        } else { 

         spinnerDelegateClass = Class.forName("android.widget.TimePickerClockDelegate"); 
        } 
        if (delegate.getClass() != spinnerDelegateClass) { 
         delegateField.set(timePicker, null); // throw out the TimePickerClockDelegate! 
         timePicker.removeAllViews(); // remove the TimePickerClockDelegate views 
         Constructor spinnerDelegateConstructor = spinnerDelegateClass.getConstructor(TimePicker.class, Context.class, AttributeSet.class, int.class, int.class); 
         spinnerDelegateConstructor.setAccessible(true); 
         // Instantiate a TimePickerSpinnerDelegate 
         delegate = spinnerDelegateConstructor.newInstance(timePicker, context, null, android.R.attr.timePickerStyle, 0); 
         delegateField.set(timePicker, delegate); // set the TimePicker.mDelegate to the spinner delegate 
         // Set up the TimePicker again, with the TimePickerSpinnerDelegate 
         timePicker.setIs24HourView(is24HourView); 
         timePicker.setCurrentHour(hourOfDay); 
         timePicker.setCurrentMinute(minute); 
         timePicker.setOnTimeChangedListener(this); 
        } 
       } 
      } catch (Exception e) { 
       throw new RuntimeException(e); 
      } 
     } 
    } 
    private static Field findField(Class objectClass, Class fieldClass, String expectedName) { 
     try { 
      Field field = objectClass.getDeclaredField(expectedName); 
      field.setAccessible(true); 
      return field; 
     } catch (NoSuchFieldException e) {} // ignore 
     // search for it if it wasn't found under the expected ivar name 
     for (Field searchField : objectClass.getDeclaredFields()) { 
      if (searchField.getType() == fieldClass) { 
       searchField.setAccessible(true); 
       return searchField; 
      } 
     } 
     return null; 
    } 
} 
+0

Sử dụng phản chiếu không phải là lưu trong tương lai. Tôi sẽ không sử dụng nó. – mars3142

Các vấn đề liên quan