1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.datetimepicker.date; 18 19 import android.content.Context; 20 import android.content.res.Resources; 21 import android.graphics.drawable.StateListDrawable; 22 import android.view.View; 23 import android.view.ViewGroup; 24 import android.view.accessibility.AccessibilityEvent; 25 import android.widget.AdapterView; 26 import android.widget.AdapterView.OnItemClickListener; 27 import android.widget.ArrayAdapter; 28 import android.widget.ListView; 29 import android.widget.TextView; 30 31 import com.android.datetimepicker.R; 32 import com.android.datetimepicker.date.DatePickerDialog.OnDateChangedListener; 33 34 import java.util.ArrayList; 35 import java.util.List; 36 37 /** 38 * Displays a selectable list of years. 39 */ 40 public class YearPickerView extends ListView implements OnItemClickListener, OnDateChangedListener { 41 private static final String TAG = "YearPickerView"; 42 43 private final DatePickerController mController; 44 private YearAdapter mAdapter; 45 private int mViewSize; 46 private int mChildSize; 47 private TextViewWithCircularIndicator mSelectedView; 48 49 /** 50 * @param context 51 */ YearPickerView(Context context, DatePickerController controller)52 public YearPickerView(Context context, DatePickerController controller) { 53 super(context); 54 mController = controller; 55 mController.registerOnDateChangedListener(this); 56 ViewGroup.LayoutParams frame = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, 57 LayoutParams.WRAP_CONTENT); 58 setLayoutParams(frame); 59 Resources res = context.getResources(); 60 mViewSize = res.getDimensionPixelOffset(R.dimen.date_picker_view_animator_height); 61 mChildSize = res.getDimensionPixelOffset(R.dimen.year_label_height); 62 setVerticalFadingEdgeEnabled(true); 63 setFadingEdgeLength(mChildSize / 3); 64 init(context); 65 setOnItemClickListener(this); 66 setSelector(new StateListDrawable()); 67 setDividerHeight(0); 68 onDateChanged(); 69 } 70 init(Context context)71 private void init(Context context) { 72 ArrayList<String> years = new ArrayList<String>(); 73 for (int year = mController.getMinYear(); year <= mController.getMaxYear(); year++) { 74 years.add(String.format("%d", year)); 75 } 76 mAdapter = new YearAdapter(context, R.layout.year_label_text_view, years); 77 setAdapter(mAdapter); 78 } 79 80 @Override onItemClick(AdapterView<?> parent, View view, int position, long id)81 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 82 mController.tryVibrate(); 83 TextViewWithCircularIndicator clickedView = (TextViewWithCircularIndicator) view; 84 if (clickedView != null) { 85 if (clickedView != mSelectedView) { 86 if (mSelectedView != null) { 87 mSelectedView.drawIndicator(false); 88 mSelectedView.requestLayout(); 89 } 90 clickedView.drawIndicator(true); 91 clickedView.requestLayout(); 92 mSelectedView = clickedView; 93 } 94 mController.onYearSelected(getYearFromTextView(clickedView)); 95 mAdapter.notifyDataSetChanged(); 96 } 97 } 98 getYearFromTextView(TextView view)99 private static int getYearFromTextView(TextView view) { 100 return Integer.parseInt(view.getText().toString()); 101 } 102 103 private class YearAdapter extends ArrayAdapter<String> { 104 YearAdapter(Context context, int resource, List<String> objects)105 public YearAdapter(Context context, int resource, List<String> objects) { 106 super(context, resource, objects); 107 } 108 109 @Override getView(int position, View convertView, ViewGroup parent)110 public View getView(int position, View convertView, ViewGroup parent) { 111 TextViewWithCircularIndicator v = (TextViewWithCircularIndicator) 112 super.getView(position, convertView, parent); 113 v.requestLayout(); 114 int year = getYearFromTextView(v); 115 boolean selected = mController.getSelectedDay().year == year; 116 v.drawIndicator(selected); 117 if (selected) { 118 mSelectedView = v; 119 } 120 return v; 121 } 122 } 123 postSetSelectionCentered(final int position)124 public void postSetSelectionCentered(final int position) { 125 postSetSelectionFromTop(position, mViewSize / 2 - mChildSize / 2); 126 } 127 postSetSelectionFromTop(final int position, final int offset)128 public void postSetSelectionFromTop(final int position, final int offset) { 129 post(new Runnable() { 130 131 @Override 132 public void run() { 133 setSelectionFromTop(position, offset); 134 requestLayout(); 135 } 136 }); 137 } 138 getFirstPositionOffset()139 public int getFirstPositionOffset() { 140 final View firstChild = getChildAt(0); 141 if (firstChild == null) { 142 return 0; 143 } 144 return firstChild.getTop(); 145 } 146 147 @Override onDateChanged()148 public void onDateChanged() { 149 mAdapter.notifyDataSetChanged(); 150 postSetSelectionCentered(mController.getSelectedDay().year - mController.getMinYear()); 151 } 152 153 @Override onInitializeAccessibilityEvent(AccessibilityEvent event)154 public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 155 super.onInitializeAccessibilityEvent(event); 156 if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) { 157 event.setFromIndex(0); 158 event.setToIndex(0); 159 } 160 } 161 } 162