Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5fa91503 authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Android (Google) Code Review
Browse files

Merge "Date/time pickers and calendar view not handling locale change."

parents ad3f935c f5926962
Loading
Loading
Loading
Loading
+62 −12
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import com.android.internal.R;
import android.annotation.Widget;
import android.app.Service;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.graphics.Canvas;
@@ -238,21 +239,11 @@ public class CalendarView extends FrameLayout {
     */
    private String[] mDayLabels;

    /**
     * Temporary instance to avoid multiple instantiations.
     */
    private Calendar mTempDate = Calendar.getInstance();

    /**
     * The first day of the week.
     */
    private int mFirstDayOfWeek;

    /**
     * The first day of the focused month.
     */
    private Calendar mFirstDayOfMonth = Calendar.getInstance();

    /**
     * Which month should be displayed/highlighted [0-11].
     */
@@ -288,21 +279,36 @@ public class CalendarView extends FrameLayout {
     */
    private ScrollStateRunnable mScrollStateChangedRunnable = new ScrollStateRunnable();

    /**
     * Temporary instance to avoid multiple instantiations.
     */
    private Calendar mTempDate;

    /**
     * The first day of the focused month.
     */
    private Calendar mFirstDayOfMonth;

    /**
     * The start date of the range supported by this picker.
     */
    private Calendar mMinDate = Calendar.getInstance();
    private Calendar mMinDate;

    /**
     * The end date of the range supported by this picker.
     */
    private Calendar mMaxDate = Calendar.getInstance();
    private Calendar mMaxDate;

    /**
     * Date format for parsing dates.
     */
    private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);

    /**
     * The current locale.
     */
    private Locale mCurrentLocale;

    /**
     * The callback used to indicate the user changes the date.
     */
@@ -330,6 +336,9 @@ public class CalendarView extends FrameLayout {
    public CalendarView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, 0);

        // initialization based on locale
        setCurrentLocale(Locale.getDefault());

        TypedValue calendarViewStyle = new TypedValue();
        context.getTheme().resolveAttribute(R.attr.calendarViewStyle, calendarViewStyle, true);
        TypedArray attributesArray = context.obtainStyledAttributes(calendarViewStyle.resourceId,
@@ -413,6 +422,12 @@ public class CalendarView extends FrameLayout {
        return mListView.isEnabled();
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setCurrentLocale(newConfig.locale);
    }

    /**
     * Gets the minimal date supported by this {@link CalendarView} in milliseconds
     * since January 1, 1970 00:00:00 in {@link TimeZone#getDefault()} time
@@ -623,6 +638,41 @@ public class CalendarView extends FrameLayout {
        goTo(mTempDate, animate, true, center);
    }

    /**
     * Sets the current locale.
     *
     * @param locale The current locale.
     */
    private void setCurrentLocale(Locale locale) {
        if (locale.equals(mCurrentLocale)) {
            return;
        }

        mCurrentLocale = locale;

        mTempDate = getCalendarForLocale(mTempDate, locale);
        mFirstDayOfMonth = getCalendarForLocale(mFirstDayOfMonth, locale);
        mMinDate = getCalendarForLocale(mMinDate, locale);
        mMaxDate = getCalendarForLocale(mMaxDate, locale);
    }

    /**
     * Gets a calendar for locale bootstrapped with the value of a given calendar.
     *
     * @param oldCalendar The old calendar.
     * @param locale The locale.
     */
    private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
        if (oldCalendar == null) {
            return Calendar.getInstance(locale);
        } else {
            final long currentTimeMillis = oldCalendar.getTimeInMillis();
            Calendar newCalendar = Calendar.getInstance(locale);
            newCalendar.setTimeInMillis(currentTimeMillis);
            return newCalendar;
        }
    }

    /**
     * @return True if the <code>firstDate</code> is the same as the <code>
     * secondDate</code>.
+65 −30
Original line number Diff line number Diff line
@@ -16,10 +16,9 @@

package android.widget;

import com.android.internal.R;

import android.annotation.Widget;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
@@ -33,6 +32,8 @@ import android.view.LayoutInflater;
import android.view.accessibility.AccessibilityEvent;
import android.widget.NumberPicker.OnValueChangeListener;

import com.android.internal.R;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
@@ -89,23 +90,23 @@ public class DatePicker extends FrameLayout {

    private final CalendarView mCalendarView;

    private OnDateChangedListener mOnDateChangedListener;
    private Locale mCurrentLocale;

    private Locale mMonthLocale;
    private OnDateChangedListener mOnDateChangedListener;

    private final Calendar mTempDate = Calendar.getInstance();
    private String[] mShortMonths;

    private final int mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1;
    private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);

    private final String[] mShortMonths = new String[mNumberOfMonths];
    private int mNumberOfMonths;

    private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);
    private Calendar mTempDate;

    private final Calendar mMinDate = Calendar.getInstance();
    private Calendar mMinDate;

    private final Calendar mMaxDate = Calendar.getInstance();
    private Calendar mMaxDate;

    private final Calendar mCurrentDate = Calendar.getInstance();
    private Calendar mCurrentDate;

    private boolean mIsEnabled = DEFAULT_ENABLED_STATE;

@@ -137,6 +138,9 @@ public class DatePicker extends FrameLayout {
    public DatePicker(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        // initialization based on locale
        setCurrentLocale(Locale.getDefault());

        TypedArray attributesArray = context.obtainStyledAttributes(attrs, R.styleable.DatePicker,
                defStyle, 0);
        boolean spinnersShown = attributesArray.getBoolean(R.styleable.DatePicker_spinnersShown,
@@ -213,7 +217,7 @@ public class DatePicker extends FrameLayout {
        mMonthSpinner = (NumberPicker) findViewById(R.id.month);
        mMonthSpinner.setMinValue(0);
        mMonthSpinner.setMaxValue(mNumberOfMonths - 1);
        mMonthSpinner.setDisplayedValues(getShortMonths());
        mMonthSpinner.setDisplayedValues(mShortMonths);
        mMonthSpinner.setOnLongPressUpdateInterval(200);
        mMonthSpinner.setOnValueChangedListener(onChangeListener);

@@ -363,6 +367,12 @@ public class DatePicker extends FrameLayout {
        event.getText().add(selectedDateUtterance);
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setCurrentLocale(newConfig.locale);
    }

    /**
     * Gets whether the {@link CalendarView} is shown.
     *
@@ -410,6 +420,48 @@ public class DatePicker extends FrameLayout {
        mSpinners.setVisibility(shown ? VISIBLE : GONE);
    }

    /**
     * Sets the current locale.
     *
     * @param locale The current locale.
     */
    private void setCurrentLocale(Locale locale) {
        if (locale.equals(mCurrentLocale)) {
            return;
        }

        mCurrentLocale = locale;

        mTempDate = getCalendarForLocale(mTempDate, locale);
        mMinDate = getCalendarForLocale(mMinDate, locale);
        mMaxDate = getCalendarForLocale(mMaxDate, locale);
        mCurrentDate = getCalendarForLocale(mCurrentDate, locale);

        mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1;
        mShortMonths = new String[mNumberOfMonths];
        for (int i = 0; i < mNumberOfMonths; i++) {
            mShortMonths[i] = DateUtils.getMonthString(Calendar.JANUARY + i,
                    DateUtils.LENGTH_MEDIUM);
        }
    }

    /**
     * Gets a calendar for locale bootstrapped with the value of a given calendar.
     *
     * @param oldCalendar The old calendar.
     * @param locale The locale.
     */
    private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
        if (oldCalendar == null) {
            return Calendar.getInstance(locale);
        } else {
            final long currentTimeMillis = oldCalendar.getTimeInMillis();
            Calendar newCalendar = Calendar.getInstance(locale);
            newCalendar.setTimeInMillis(currentTimeMillis);
            return newCalendar;
        }
    }

    /**
     * Reorders the spinners according to the date format that is
     * explicitly set by the user and if no such is set fall back
@@ -507,23 +559,6 @@ public class DatePicker extends FrameLayout {
        }
    }

    /**
     * @return The short month abbreviations.
     */
    private String[] getShortMonths() {
        final Locale currentLocale = Locale.getDefault();
        if (currentLocale.equals(mMonthLocale)) {
            return mShortMonths;
        } else {
            for (int i = 0; i < mNumberOfMonths; i++) {
                mShortMonths[i] = DateUtils.getMonthString(Calendar.JANUARY + i,
                        DateUtils.LENGTH_MEDIUM);
            }
            mMonthLocale = currentLocale;
            return mShortMonths;
        }
    }

    private boolean isNewDate(int year, int month, int dayOfMonth) {
        return (mCurrentDate.get(Calendar.YEAR) != year
                || mCurrentDate.get(Calendar.MONTH) != dayOfMonth
@@ -569,7 +604,7 @@ public class DatePicker extends FrameLayout {

        // make sure the month names are a zero based array
        // with the months in the month spinner
        String[] displayedValues = Arrays.copyOfRange(getShortMonths(),
        String[] displayedValues = Arrays.copyOfRange(mShortMonths,
                mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1);
        mMonthSpinner.setDisplayedValues(displayedValues);

+26 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import com.android.internal.R;

import android.annotation.Widget;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,6 +33,7 @@ import android.widget.NumberPicker.OnValueChangeListener;

import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.Locale;

/**
 * A view for selecting the time of day, in either 24 hour or AM/PM mode. The
@@ -92,6 +94,8 @@ public class TimePicker extends FrameLayout {

    private Calendar mTempCalendar;

    private Locale mCurrentLocale;

    /**
     * The callback interface used to indicate the time has been adjusted.
     */
@@ -116,6 +120,9 @@ public class TimePicker extends FrameLayout {
    public TimePicker(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        // initialization based on locale
        setCurrentLocale(Locale.getDefault());

        // process style attributes
        TypedArray attributesArray = context.obtainStyledAttributes(
                attrs, R.styleable.TimePicker, defStyle, 0);
@@ -211,8 +218,6 @@ public class TimePicker extends FrameLayout {
        updateHourControl();
        updateAmPmControl();

        // initialize to current time
        mTempCalendar = Calendar.getInstance();
        setOnTimeChangedListener(NO_OP_CHANGE_LISTENER);

        // set to current time
@@ -248,6 +253,25 @@ public class TimePicker extends FrameLayout {
        return mIsEnabled;
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setCurrentLocale(newConfig.locale);
    }

    /**
     * Sets the current locale.
     *
     * @param locale The current locale.
     */
    private void setCurrentLocale(Locale locale) {
        if (locale.equals(mCurrentLocale)) {
            return;
        }
        mCurrentLocale = locale;
        mTempCalendar = Calendar.getInstance(locale);
    }

    /**
     * Used to save / restore state of time picker
     */