YearPickerView.java revision 2e00aa34c051111529290cf23c6ba940c2c0c142
13e9818e0267619fecebd55095ab26c53eff92e93James Kung/*
23e9818e0267619fecebd55095ab26c53eff92e93James Kung * Copyright (C) 2013 The Android Open Source Project
33e9818e0267619fecebd55095ab26c53eff92e93James Kung *
43e9818e0267619fecebd55095ab26c53eff92e93James Kung * Licensed under the Apache License, Version 2.0 (the "License");
53e9818e0267619fecebd55095ab26c53eff92e93James Kung * you may not use this file except in compliance with the License.
63e9818e0267619fecebd55095ab26c53eff92e93James Kung * You may obtain a copy of the License at
73e9818e0267619fecebd55095ab26c53eff92e93James Kung *
83e9818e0267619fecebd55095ab26c53eff92e93James Kung *      http://www.apache.org/licenses/LICENSE-2.0
93e9818e0267619fecebd55095ab26c53eff92e93James Kung *
103e9818e0267619fecebd55095ab26c53eff92e93James Kung * Unless required by applicable law or agreed to in writing, software
113e9818e0267619fecebd55095ab26c53eff92e93James Kung * distributed under the License is distributed on an "AS IS" BASIS,
123e9818e0267619fecebd55095ab26c53eff92e93James Kung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133e9818e0267619fecebd55095ab26c53eff92e93James Kung * See the License for the specific language governing permissions and
143e9818e0267619fecebd55095ab26c53eff92e93James Kung * limitations under the License.
153e9818e0267619fecebd55095ab26c53eff92e93James Kung */
163e9818e0267619fecebd55095ab26c53eff92e93James Kung
173e9818e0267619fecebd55095ab26c53eff92e93James Kungpackage com.android.datetimepicker.date;
183e9818e0267619fecebd55095ab26c53eff92e93James Kung
193e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.content.Context;
202e00aa34c051111529290cf23c6ba940c2c0c142James Kungimport android.content.res.Resources;
212e00aa34c051111529290cf23c6ba940c2c0c142James Kungimport android.graphics.drawable.StateListDrawable;
222e00aa34c051111529290cf23c6ba940c2c0c142James Kungimport android.view.View;
233e9818e0267619fecebd55095ab26c53eff92e93James Kungimport android.view.ViewGroup;
242e00aa34c051111529290cf23c6ba940c2c0c142James Kungimport android.widget.AdapterView;
252e00aa34c051111529290cf23c6ba940c2c0c142James Kungimport android.widget.AdapterView.OnItemClickListener;
262e00aa34c051111529290cf23c6ba940c2c0c142James Kungimport android.widget.ArrayAdapter;
272e00aa34c051111529290cf23c6ba940c2c0c142James Kungimport android.widget.ListView;
282e00aa34c051111529290cf23c6ba940c2c0c142James Kungimport android.widget.TextView;
292e00aa34c051111529290cf23c6ba940c2c0c142James Kung
302e00aa34c051111529290cf23c6ba940c2c0c142James Kungimport com.android.datetimepicker.R;
312e00aa34c051111529290cf23c6ba940c2c0c142James Kungimport com.android.datetimepicker.date.DatePickerDialog.OnDateChangedListener;
322e00aa34c051111529290cf23c6ba940c2c0c142James Kung
332e00aa34c051111529290cf23c6ba940c2c0c142James Kungimport java.util.ArrayList;
342e00aa34c051111529290cf23c6ba940c2c0c142James Kungimport java.util.List;
353e9818e0267619fecebd55095ab26c53eff92e93James Kung
363e9818e0267619fecebd55095ab26c53eff92e93James Kung/**
372e00aa34c051111529290cf23c6ba940c2c0c142James Kung * Displays a selectable list of years.
383e9818e0267619fecebd55095ab26c53eff92e93James Kung */
392e00aa34c051111529290cf23c6ba940c2c0c142James Kungpublic class YearPickerView extends ListView implements OnItemClickListener, OnDateChangedListener {
403e9818e0267619fecebd55095ab26c53eff92e93James Kung
413e9818e0267619fecebd55095ab26c53eff92e93James Kung    private final DatePickerController mController;
422e00aa34c051111529290cf23c6ba940c2c0c142James Kung    private YearAdapter mAdapter;
432e00aa34c051111529290cf23c6ba940c2c0c142James Kung    private int mViewSize;
442e00aa34c051111529290cf23c6ba940c2c0c142James Kung    private int mChildSize;
452e00aa34c051111529290cf23c6ba940c2c0c142James Kung    private TextViewWithCircularIndicator mSelectedView;
463e9818e0267619fecebd55095ab26c53eff92e93James Kung
472e00aa34c051111529290cf23c6ba940c2c0c142James Kung    /**
482e00aa34c051111529290cf23c6ba940c2c0c142James Kung     * @param context
492e00aa34c051111529290cf23c6ba940c2c0c142James Kung     */
503e9818e0267619fecebd55095ab26c53eff92e93James Kung    public YearPickerView(Context context, DatePickerController controller) {
513e9818e0267619fecebd55095ab26c53eff92e93James Kung        super(context);
523e9818e0267619fecebd55095ab26c53eff92e93James Kung        mController = controller;
532e00aa34c051111529290cf23c6ba940c2c0c142James Kung        mController.registerOnDateChangedListener(this);
542e00aa34c051111529290cf23c6ba940c2c0c142James Kung        setVerticalFadingEdgeEnabled(true);
553e9818e0267619fecebd55095ab26c53eff92e93James Kung        ViewGroup.LayoutParams frame = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT,
563e9818e0267619fecebd55095ab26c53eff92e93James Kung                LayoutParams.WRAP_CONTENT);
572e00aa34c051111529290cf23c6ba940c2c0c142James Kung        setLayoutParams(frame);
582e00aa34c051111529290cf23c6ba940c2c0c142James Kung        Resources res = context.getResources();
592e00aa34c051111529290cf23c6ba940c2c0c142James Kung        mViewSize = res.getDimensionPixelOffset(R.dimen.pager_height);
602e00aa34c051111529290cf23c6ba940c2c0c142James Kung        mChildSize = res.getDimensionPixelOffset(R.dimen.year_label_height);
612e00aa34c051111529290cf23c6ba940c2c0c142James Kung        setFadingEdgeLength(mChildSize / 3);
622e00aa34c051111529290cf23c6ba940c2c0c142James Kung        init(context);
632e00aa34c051111529290cf23c6ba940c2c0c142James Kung        setOnItemClickListener(this);
642e00aa34c051111529290cf23c6ba940c2c0c142James Kung        setSelector(new StateListDrawable());
652e00aa34c051111529290cf23c6ba940c2c0c142James Kung        setDividerHeight(0);
662e00aa34c051111529290cf23c6ba940c2c0c142James Kung        onDateChanged();
672e00aa34c051111529290cf23c6ba940c2c0c142James Kung    }
682e00aa34c051111529290cf23c6ba940c2c0c142James Kung
692e00aa34c051111529290cf23c6ba940c2c0c142James Kung    private void init(Context context) {
702e00aa34c051111529290cf23c6ba940c2c0c142James Kung        ArrayList<String> years = new ArrayList<String>();
712e00aa34c051111529290cf23c6ba940c2c0c142James Kung        for (int year = mController.getMinYear(); year <= mController.getMaxYear(); year++) {
722e00aa34c051111529290cf23c6ba940c2c0c142James Kung            years.add(Integer.valueOf(year).toString());
732e00aa34c051111529290cf23c6ba940c2c0c142James Kung        }
742e00aa34c051111529290cf23c6ba940c2c0c142James Kung        mAdapter = new YearAdapter(context, R.layout.year_label_text_view, years);
752e00aa34c051111529290cf23c6ba940c2c0c142James Kung        setAdapter(mAdapter);
762e00aa34c051111529290cf23c6ba940c2c0c142James Kung    }
772e00aa34c051111529290cf23c6ba940c2c0c142James Kung
782e00aa34c051111529290cf23c6ba940c2c0c142James Kung    @Override
792e00aa34c051111529290cf23c6ba940c2c0c142James Kung    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
802e00aa34c051111529290cf23c6ba940c2c0c142James Kung        mController.tryVibrate();
812e00aa34c051111529290cf23c6ba940c2c0c142James Kung        TextViewWithCircularIndicator clickedView = (TextViewWithCircularIndicator) view;
822e00aa34c051111529290cf23c6ba940c2c0c142James Kung        if (mSelectedView != clickedView) {
832e00aa34c051111529290cf23c6ba940c2c0c142James Kung            mSelectedView.drawIndicator(false);
842e00aa34c051111529290cf23c6ba940c2c0c142James Kung            mSelectedView.requestLayout();
852e00aa34c051111529290cf23c6ba940c2c0c142James Kung            clickedView.drawIndicator(true);
862e00aa34c051111529290cf23c6ba940c2c0c142James Kung            clickedView.requestLayout();
872e00aa34c051111529290cf23c6ba940c2c0c142James Kung            mSelectedView = clickedView;
882e00aa34c051111529290cf23c6ba940c2c0c142James Kung        }
892e00aa34c051111529290cf23c6ba940c2c0c142James Kung        mController.onYearSelected(getYearFromTextView(clickedView));
902e00aa34c051111529290cf23c6ba940c2c0c142James Kung        mAdapter.notifyDataSetChanged();
913e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
923e9818e0267619fecebd55095ab26c53eff92e93James Kung
932e00aa34c051111529290cf23c6ba940c2c0c142James Kung    private int getYearFromTextView(TextView view) {
942e00aa34c051111529290cf23c6ba940c2c0c142James Kung        return Integer.valueOf(view.getText().toString());
953e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
963e9818e0267619fecebd55095ab26c53eff92e93James Kung
972e00aa34c051111529290cf23c6ba940c2c0c142James Kung    private class YearAdapter extends ArrayAdapter<String> {
982e00aa34c051111529290cf23c6ba940c2c0c142James Kung
992e00aa34c051111529290cf23c6ba940c2c0c142James Kung        public YearAdapter(Context context, int resource, List<String> objects) {
1002e00aa34c051111529290cf23c6ba940c2c0c142James Kung            super(context, resource, objects);
1012e00aa34c051111529290cf23c6ba940c2c0c142James Kung        }
1022e00aa34c051111529290cf23c6ba940c2c0c142James Kung
1032e00aa34c051111529290cf23c6ba940c2c0c142James Kung        @Override
1042e00aa34c051111529290cf23c6ba940c2c0c142James Kung        public View getView(int position, View convertView, ViewGroup parent) {
1052e00aa34c051111529290cf23c6ba940c2c0c142James Kung            TextViewWithCircularIndicator v = (TextViewWithCircularIndicator)
1062e00aa34c051111529290cf23c6ba940c2c0c142James Kung                    super.getView(position, convertView, parent);
1072e00aa34c051111529290cf23c6ba940c2c0c142James Kung            v.requestLayout();
1082e00aa34c051111529290cf23c6ba940c2c0c142James Kung            int year = getYearFromTextView(v);
1092e00aa34c051111529290cf23c6ba940c2c0c142James Kung            boolean selected = mController.getSelectedDay().year == year;
1102e00aa34c051111529290cf23c6ba940c2c0c142James Kung            v.drawIndicator(selected);
1112e00aa34c051111529290cf23c6ba940c2c0c142James Kung            if (selected) {
1122e00aa34c051111529290cf23c6ba940c2c0c142James Kung                mSelectedView = v;
1132e00aa34c051111529290cf23c6ba940c2c0c142James Kung            }
1142e00aa34c051111529290cf23c6ba940c2c0c142James Kung            return v;
1152e00aa34c051111529290cf23c6ba940c2c0c142James Kung        }
1162e00aa34c051111529290cf23c6ba940c2c0c142James Kung    }
1172e00aa34c051111529290cf23c6ba940c2c0c142James Kung
1182e00aa34c051111529290cf23c6ba940c2c0c142James Kung    public void postSetSelection(final int position) {
1192e00aa34c051111529290cf23c6ba940c2c0c142James Kung        post(new Runnable() {
1202e00aa34c051111529290cf23c6ba940c2c0c142James Kung
1212e00aa34c051111529290cf23c6ba940c2c0c142James Kung            @Override
1222e00aa34c051111529290cf23c6ba940c2c0c142James Kung            public void run() {
1232e00aa34c051111529290cf23c6ba940c2c0c142James Kung                setSelection(position);
1242e00aa34c051111529290cf23c6ba940c2c0c142James Kung                requestLayout();
1252e00aa34c051111529290cf23c6ba940c2c0c142James Kung            }
1262e00aa34c051111529290cf23c6ba940c2c0c142James Kung        });
1272e00aa34c051111529290cf23c6ba940c2c0c142James Kung    }
1282e00aa34c051111529290cf23c6ba940c2c0c142James Kung
1292e00aa34c051111529290cf23c6ba940c2c0c142James Kung    public void postSetSelectionFromTop(final int position) {
1302e00aa34c051111529290cf23c6ba940c2c0c142James Kung        post(new Runnable() {
1312e00aa34c051111529290cf23c6ba940c2c0c142James Kung
1322e00aa34c051111529290cf23c6ba940c2c0c142James Kung            @Override
1332e00aa34c051111529290cf23c6ba940c2c0c142James Kung            public void run() {
1342e00aa34c051111529290cf23c6ba940c2c0c142James Kung                setSelectionFromTop(position, mViewSize / 2 - mChildSize / 2);
1352e00aa34c051111529290cf23c6ba940c2c0c142James Kung                requestLayout();
1362e00aa34c051111529290cf23c6ba940c2c0c142James Kung            }
1372e00aa34c051111529290cf23c6ba940c2c0c142James Kung        });
1383e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1393e9818e0267619fecebd55095ab26c53eff92e93James Kung
1403e9818e0267619fecebd55095ab26c53eff92e93James Kung    @Override
1412e00aa34c051111529290cf23c6ba940c2c0c142James Kung    public void onDateChanged() {
1422e00aa34c051111529290cf23c6ba940c2c0c142James Kung        mAdapter.notifyDataSetChanged();
1432e00aa34c051111529290cf23c6ba940c2c0c142James Kung        postSetSelectionFromTop(mController.getSelectedDay().year - mController.getMinYear());
1443e9818e0267619fecebd55095ab26c53eff92e93James Kung    }
1453e9818e0267619fecebd55095ab26c53eff92e93James Kung}
146