SelectCalendarsSimpleAdapter.java revision 189eaf7c678d0bd8218d667c9aa41ea640859acf
1/* 2 * Copyright (C) 2010 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 17package com.android.calendar.selectcalendars; 18 19import com.android.calendar.R; 20 21import android.content.Context; 22import android.content.res.Configuration; 23import android.content.res.Resources; 24import android.database.Cursor; 25import android.graphics.drawable.Drawable; 26import android.provider.Calendar.Calendars; 27import android.text.TextUtils; 28import android.view.LayoutInflater; 29import android.view.View; 30import android.view.ViewGroup; 31import android.widget.BaseAdapter; 32import android.widget.ListAdapter; 33import android.widget.RelativeLayout; 34import android.widget.TextView; 35 36public class SelectCalendarsSimpleAdapter extends BaseAdapter implements ListAdapter { 37 private static final String TAG = "SelectCalendarsAdapter"; 38 private static int SELECTED_COLOR_CHIP_SIZE = 16; 39 private static int UNSELECTED_COLOR_CHIP_SIZE = 10; 40 private static int COLOR_CHIP_LEFT_MARGIN = 20; 41 private static int COLOR_CHIP_RIGHT_MARGIN = 8; 42 private static int COLOR_CHIP_TOP_OFFSET = 5; 43 44 private Drawable[] mBackgrounds = new Drawable[16]; 45 46 private static final int SELECTED_UNDER_NORMAL = 0; 47 private static final int BOTTOM_SELECTED_UNDER_NORMAL = 1; 48 private static final int BOTTOM_SELECTED_UNDER_SELECTED = 2; 49 private static final int SELECTED_UNDER_SELECTED = 3; 50 private static final int NORMAL_UNDER_NORMAL = 4; 51 private static final int BOTTOM_NORMAL_UNDER_NORMAL = 5; 52 private static final int BOTTOM_NORMAL_UNDER_SELECTED = 6; 53 private static final int NORMAL_UNDER_SELECTED = 7; 54 private static final int IS_SELECTED = 1 << 0; 55 private static final int IS_TOP = 1 << 1; 56 private static final int IS_BOTTOM = 1 << 2; 57 private static final int IS_BELOW_SELECTED = 1 << 3; 58 59 60 private LayoutInflater mInflater; 61 private int mLayout; 62 private int mOrientation; 63 private CalendarRow[] mData; 64 private Cursor mCursor; 65 private int mRowCount = 0; 66 67 private int mIdColumn; 68 private int mNameColumn; 69 private int mColorColumn; 70 private int mSelectedColumn; 71 private float mScale = 0; 72 73 private class CalendarRow { 74 long id; 75 String displayName; 76 int color; 77 boolean selected; 78 } 79 80 public SelectCalendarsSimpleAdapter(Context context, int layout, Cursor c) { 81 super(); 82 mLayout = layout; 83 mOrientation = context.getResources().getConfiguration().orientation; 84 initData(c); 85 mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 86 Resources res = context.getResources(); 87 if (mScale == 0) { 88 mScale = res.getDisplayMetrics().density; 89 SELECTED_COLOR_CHIP_SIZE *= mScale; 90 UNSELECTED_COLOR_CHIP_SIZE *= mScale; 91 COLOR_CHIP_LEFT_MARGIN *= mScale; 92 COLOR_CHIP_RIGHT_MARGIN *= mScale; 93 COLOR_CHIP_TOP_OFFSET *= mScale; 94 } 95 initBackgrounds(res); 96 } 97 98 /** 99 * Sets up the background drawables for the calendars list 100 * 101 * @param res The context's resources 102 */ 103 private void initBackgrounds(Resources res) { 104 mBackgrounds[0] = 105 res.getDrawable(R.drawable.calname_nomal_holo_light); 106 mBackgrounds[IS_TOP] = mBackgrounds[0]; 107 108 mBackgrounds[IS_SELECTED] = 109 res.getDrawable(R.drawable.calname_select_undernomal_holo_light); 110 mBackgrounds[IS_SELECTED | IS_TOP] = mBackgrounds[IS_SELECTED]; 111 112 mBackgrounds[IS_SELECTED | IS_BOTTOM] = 113 res.getDrawable(R.drawable.calname_bottom_select_undernomal_holo_light); 114 mBackgrounds[IS_SELECTED | IS_TOP | IS_BOTTOM] = mBackgrounds[IS_SELECTED | IS_BOTTOM]; 115 116 mBackgrounds[IS_SELECTED | IS_BOTTOM | IS_BELOW_SELECTED] = 117 res.getDrawable(R.drawable.calname_bottom_select_underselect_holo_light); 118 mBackgrounds[IS_SELECTED | IS_TOP | IS_BOTTOM | IS_BELOW_SELECTED] = mBackgrounds[ 119 IS_SELECTED | IS_BOTTOM | IS_BELOW_SELECTED]; 120 121 mBackgrounds[IS_SELECTED | IS_BELOW_SELECTED] = 122 res.getDrawable(R.drawable.calname_select_underselect_holo_light); 123 mBackgrounds[IS_SELECTED | IS_TOP | IS_BELOW_SELECTED] = mBackgrounds[IS_SELECTED 124 | IS_BELOW_SELECTED]; 125 126 mBackgrounds[IS_BOTTOM] = 127 res.getDrawable(R.drawable.calname_bottom_nomal_holo_light); 128 mBackgrounds[IS_TOP | IS_BOTTOM] = mBackgrounds[IS_BOTTOM]; 129 130 mBackgrounds[IS_BOTTOM | IS_BELOW_SELECTED] = 131 res.getDrawable(R.drawable.calname_bottom_nomal_underselect_holo_light); 132 mBackgrounds[IS_TOP | IS_BOTTOM | IS_BELOW_SELECTED] = mBackgrounds[IS_BOTTOM 133 | IS_BELOW_SELECTED]; 134 135 mBackgrounds[IS_BELOW_SELECTED] = 136 res.getDrawable(R.drawable.calname_nomal_underselect_holo_light); 137 mBackgrounds[IS_TOP | IS_BELOW_SELECTED] = mBackgrounds[IS_BELOW_SELECTED]; 138 } 139 140 private void initData(Cursor c) { 141 if (mCursor != null && c != mCursor) { 142 mCursor.close(); 143 } 144 if (c == null) { 145 mCursor = c; 146 mRowCount = 0; 147 mData = null; 148 return; 149 } 150 // TODO create a broadcast listener for ACTION_PROVIDER_CHANGED to update the cursor 151 mCursor = c; 152 mIdColumn = c.getColumnIndexOrThrow(Calendars._ID); 153 mNameColumn = c.getColumnIndexOrThrow(Calendars.DISPLAY_NAME); 154 mColorColumn = c.getColumnIndexOrThrow(Calendars.COLOR); 155 mSelectedColumn = c.getColumnIndexOrThrow(Calendars.SELECTED); 156 157 mRowCount = c.getCount(); 158 mData = new CalendarRow[(c.getCount() + 2)]; 159 c.moveToPosition(-1); 160 int p = 0; 161 while (c.moveToNext()) { 162 mData[p] = new CalendarRow(); 163 mData[p].id = c.getLong(mIdColumn); 164 mData[p].displayName = c.getString(mNameColumn); 165 mData[p].color = c.getInt(mColorColumn); 166 mData[p].selected = c.getInt(mSelectedColumn) != 0; 167 p++; 168 } 169 } 170 171 public void changeCursor(Cursor c) { 172 initData(c); 173 notifyDataSetChanged(); 174 } 175 176 public View getView(int position, View convertView, ViewGroup parent) { 177 if (position >= mRowCount) { 178 return null; 179 } 180 String name = mData[position].displayName; 181 boolean selected = mData[position].selected; 182 Drawable bg = getBackground(position, selected); 183 184 185 int color = mData[position].color; 186 View view; 187 if (convertView == null) { 188 view = mInflater.inflate(mLayout, parent, false); 189 } else { 190 view = convertView; 191 } 192 193 View colorView = view.findViewById(R.id.color); 194 RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( 195 SELECTED_COLOR_CHIP_SIZE, SELECTED_COLOR_CHIP_SIZE); 196 params.leftMargin = COLOR_CHIP_LEFT_MARGIN; 197 params.rightMargin = COLOR_CHIP_RIGHT_MARGIN; 198 // This offset is needed because the assets include the bottom of the 199 // previous item 200 params.topMargin = COLOR_CHIP_TOP_OFFSET; 201 if (!selected) { 202 params.height = UNSELECTED_COLOR_CHIP_SIZE; 203 params.width = UNSELECTED_COLOR_CHIP_SIZE; 204 params.leftMargin += (SELECTED_COLOR_CHIP_SIZE - UNSELECTED_COLOR_CHIP_SIZE) / 2; 205 params.topMargin += (SELECTED_COLOR_CHIP_SIZE - UNSELECTED_COLOR_CHIP_SIZE) / 2; 206 } 207 colorView.setLayoutParams(params); 208 colorView.setBackgroundColor(color); 209 210 setText(view, R.id.calendar, name); 211 view.setBackgroundDrawable(bg); 212 view.invalidate(); 213 return view; 214 } 215 216 /** 217 * @param position position of the calendar item 218 * @param selected whether it is selected or not 219 * @return the drawable to use for this view 220 */ 221 protected Drawable getBackground(int position, boolean selected) { 222 int bg; 223 bg = selected ? IS_SELECTED : 0; 224 bg |= position == 0 ? IS_TOP : 0; 225 bg |= position == mData.length - 1 ? IS_BOTTOM : 0; 226 bg |= ((position == 0 && mOrientation != Configuration.ORIENTATION_LANDSCAPE && selected) 227 || (position > 0 && mData[position - 1].selected)) ? IS_BELOW_SELECTED : 0; 228 return mBackgrounds[bg]; 229 } 230 231 private static void setText(View view, int id, String text) { 232 if (TextUtils.isEmpty(text)) { 233 return; 234 } 235 TextView textView = (TextView) view.findViewById(id); 236 textView.setText(text); 237 } 238 239 public int getCount() { 240 return mRowCount; 241 } 242 243 public Object getItem(int position) { 244 if (position >= mRowCount) { 245 return null; 246 } 247 CalendarRow item = mData[position]; 248 return item; 249 } 250 251 public long getItemId(int position) { 252 if (position >= mRowCount) { 253 return 0; 254 } 255 return mData[position].id; 256 } 257 258 public void setVisible(int position, int visible) { 259 mData[position].selected = visible != 0; 260 notifyDataSetChanged(); 261 } 262 263 public int getVisible(int position) { 264 return mData[position].selected ? 1 : 0; 265 } 266 267} 268