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