Android API 21 - TimePicker widget

前端 未结 2 736
萌比男神i
萌比男神i 2020-12-10 03:20

I\'ve got a problem with the TimePicker widget on API 21. Until API 19 the TimePicker was an up-/down-list like iOS, but in 21+ it\'s round, like t

相关标签:
2条回答
  • 2020-12-10 03:36

    You can specify the spinner-style time picker by setting the timePickerMode attribute to "spinner". The default value on Material is "clock".

    <TimePicker
        ...
        android:timePickerMode="spinner" />
    
    0 讨论(0)
  • 2020-12-10 03:41

    You can Programatically use the spinner mode using the custom class. For earlier versions From lolipop it will change the timepicker mode from clock to spinner and it's also allow you to set disable selection of time after a particular time (using setmax() & setmin()). In the below code i used set max() to limit the maximum time.

    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 讨论(0)
提交回复
热议问题