SelectCalendarsSimpleAdapter.java revision 4a7580153fb14680612e53a2e02e06b1c68b0197
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.util.Log; 30import android.view.LayoutInflater; 31import android.view.View; 32import android.view.ViewGroup; 33import android.view.ViewGroup.LayoutParams; 34import android.widget.BaseAdapter; 35import android.widget.CheckBox; 36import android.widget.ListAdapter; 37import android.widget.RelativeLayout; 38import android.widget.TextView; 39 40public class SelectCalendarsSimpleAdapter extends BaseAdapter implements ListAdapter { 41 private static final String TAG = "SelectCalendarsAdapter"; 42 private static int SELECTED_COLOR_CHIP_SIZE = 16; 43 private static int UNSELECTED_COLOR_CHIP_SIZE = 10; 44 private static int COLOR_CHIP_LEFT_MARGIN = 20; 45 private static int COLOR_CHIP_RIGHT_MARGIN = 8; 46 private static int COLOR_CHIP_TOP_OFFSET = 5; 47 private static int BOTTOM_ITEM_HEIGHT = 64; 48 private static int NORMAL_ITEM_HEIGHT = 48; 49 50 private static final int IS_SELECTED = 1 << 0; 51 private static final int IS_TOP = 1 << 1; 52 private static final int IS_BOTTOM = 1 << 2; 53 private static final int IS_BELOW_SELECTED = 1 << 3; 54 55 56 private LayoutInflater mInflater; 57 Resources mRes; 58 private int mLayout; 59 private int mOrientation; 60 private CalendarRow[] mData; 61 private Cursor mCursor; 62 private int mRowCount = 0; 63 64 private int mIdColumn; 65 private int mNameColumn; 66 private int mColorColumn; 67 private int mVisibleColumn; 68 private int mOwnerAccountColumn; 69 private float mScale = 0; 70 private int mColorCalendarVisible; 71 private int mColorCalendarHidden; 72 private int mColorCalendarSecondaryVisible; 73 private int mColorCalendarSecondaryHidden; 74 75 private class CalendarRow { 76 long id; 77 String displayName; 78 String ownerAccount; 79 int color; 80 boolean selected; 81 } 82 83 public SelectCalendarsSimpleAdapter(Context context, int layout, Cursor c) { 84 super(); 85 mLayout = layout; 86 mOrientation = context.getResources().getConfiguration().orientation; 87 initData(c); 88 mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 89 mRes = context.getResources(); 90 mColorCalendarVisible = mRes.getColor(R.color.calendar_visible); 91 mColorCalendarHidden = mRes.getColor(R.color.calendar_hidden); 92 mColorCalendarSecondaryVisible = mRes.getColor(R.color.calendar_secondary_visible); 93 mColorCalendarSecondaryHidden = mRes.getColor(R.color.calendar_secondary_hidden); 94 95 if (mScale == 0) { 96 mScale = mRes.getDisplayMetrics().density; 97 SELECTED_COLOR_CHIP_SIZE *= mScale; 98 UNSELECTED_COLOR_CHIP_SIZE *= mScale; 99 COLOR_CHIP_LEFT_MARGIN *= mScale; 100 COLOR_CHIP_RIGHT_MARGIN *= mScale; 101 COLOR_CHIP_TOP_OFFSET *= mScale; 102 BOTTOM_ITEM_HEIGHT *= mScale; 103 NORMAL_ITEM_HEIGHT *= mScale; 104 } 105 } 106 107 private static class TabletCalendarItemBackgrounds { 108 static private int[] mBackgrounds = null; 109 110 /** 111 * Sets up the background drawables for the calendars list 112 * 113 * @param res The context's resources 114 */ 115 static int[] getBackgrounds() { 116 // Not thread safe. Ok if called only from main thread 117 if (mBackgrounds != null) { 118 return mBackgrounds; 119 } 120 121 mBackgrounds = new int[16]; 122 123 mBackgrounds[0] = R.drawable.calname_unselected; 124 125 mBackgrounds[IS_SELECTED] = R.drawable.calname_select_underunselected; 126 127 mBackgrounds[IS_SELECTED | IS_BOTTOM] = 128 R.drawable.calname_bottom_select_underunselected; 129 130 mBackgrounds[IS_SELECTED | IS_BOTTOM | IS_BELOW_SELECTED] = 131 R.drawable.calname_bottom_select_underselect; 132 mBackgrounds[IS_SELECTED | IS_TOP | IS_BOTTOM | IS_BELOW_SELECTED] = mBackgrounds[ 133 IS_SELECTED | IS_BOTTOM | IS_BELOW_SELECTED]; 134 mBackgrounds[IS_SELECTED | IS_TOP | IS_BOTTOM] = mBackgrounds[IS_SELECTED | IS_BOTTOM 135 | IS_BELOW_SELECTED]; 136 137 mBackgrounds[IS_SELECTED | IS_BELOW_SELECTED] = R.drawable.calname_select_underselect; 138 mBackgrounds[IS_SELECTED | IS_TOP | IS_BELOW_SELECTED] = mBackgrounds[IS_SELECTED 139 | IS_BELOW_SELECTED]; 140 mBackgrounds[IS_SELECTED | IS_TOP] = mBackgrounds[IS_SELECTED | IS_BELOW_SELECTED]; 141 142 mBackgrounds[IS_BOTTOM] = R.drawable.calname_bottom_unselected; 143 144 mBackgrounds[IS_BOTTOM | IS_BELOW_SELECTED] = 145 R.drawable.calname_bottom_unselected_underselect; 146 mBackgrounds[IS_TOP | IS_BOTTOM | IS_BELOW_SELECTED] = mBackgrounds[IS_BOTTOM 147 | IS_BELOW_SELECTED]; 148 mBackgrounds[IS_TOP | IS_BOTTOM] = mBackgrounds[IS_BOTTOM | IS_BELOW_SELECTED]; 149 150 mBackgrounds[IS_BELOW_SELECTED] = R.drawable.calname_unselected_underselect; 151 mBackgrounds[IS_TOP | IS_BELOW_SELECTED] = mBackgrounds[IS_BELOW_SELECTED]; 152 mBackgrounds[IS_TOP] = mBackgrounds[IS_BELOW_SELECTED]; 153 return mBackgrounds; 154 } 155 } 156 157 private void initData(Cursor c) { 158 if (mCursor != null && c != mCursor) { 159 mCursor.close(); 160 } 161 if (c == null) { 162 mCursor = c; 163 mRowCount = 0; 164 mData = null; 165 return; 166 } 167 // TODO create a broadcast listener for ACTION_PROVIDER_CHANGED to update the cursor 168 mCursor = c; 169 mIdColumn = c.getColumnIndexOrThrow(Calendars._ID); 170 mNameColumn = c.getColumnIndexOrThrow(Calendars.CALENDAR_DISPLAY_NAME); 171 mColorColumn = c.getColumnIndexOrThrow(Calendars.CALENDAR_COLOR); 172 mVisibleColumn = c.getColumnIndexOrThrow(Calendars.VISIBLE); 173 mOwnerAccountColumn = c.getColumnIndexOrThrow(Calendars.OWNER_ACCOUNT); 174 175 mRowCount = c.getCount(); 176 mData = new CalendarRow[(c.getCount())]; 177 c.moveToPosition(-1); 178 int p = 0; 179 while (c.moveToNext()) { 180 mData[p] = new CalendarRow(); 181 mData[p].id = c.getLong(mIdColumn); 182 mData[p].displayName = c.getString(mNameColumn); 183 mData[p].color = c.getInt(mColorColumn); 184 mData[p].selected = c.getInt(mVisibleColumn) != 0; 185 mData[p].ownerAccount = c.getString(mOwnerAccountColumn); 186 p++; 187 } 188 } 189 190 public void changeCursor(Cursor c) { 191 initData(c); 192 notifyDataSetChanged(); 193 } 194 195 public View getView(int position, View convertView, ViewGroup parent) { 196 if (position >= mRowCount) { 197 return null; 198 } 199 String name = mData[position].displayName; 200 boolean selected = mData[position].selected; 201 202 int color = Utils.getDisplayColorFromColor(mData[position].color); 203 View view; 204 if (convertView == null) { 205 view = mInflater.inflate(mLayout, parent, false); 206 } else { 207 view = convertView; 208 } 209 210 TextView calendarName = (TextView) view.findViewById(R.id.calendar); 211 calendarName.setText(name); 212 213 View colorView = view.findViewById(R.id.color); 214 colorView.setBackgroundColor(color); 215 216 CheckBox syncCheckBox = (CheckBox) view.findViewById(R.id.sync); 217 if (syncCheckBox != null) { 218 // Full screen layout 219 syncCheckBox.setChecked(selected); 220 221 int textColor; 222 if (selected) { 223 textColor = mColorCalendarVisible; 224 } else { 225 textColor = mColorCalendarHidden; 226 } 227 calendarName.setTextColor(textColor); 228 LayoutParams layoutParam = calendarName.getLayoutParams(); 229 230 TextView secondaryText = (TextView) view.findViewById(R.id.status); 231 if (!TextUtils.isEmpty(mData[position].ownerAccount) 232 && !mData[position].ownerAccount.equals(name) 233 && !mData[position].ownerAccount.endsWith("calendar.google.com")) { 234 int secondaryColor; 235 if (selected) { 236 secondaryColor = mColorCalendarSecondaryVisible; 237 } else { 238 secondaryColor = mColorCalendarSecondaryHidden; 239 } 240 secondaryText.setText(mData[position].ownerAccount); 241 secondaryText.setTextColor(secondaryColor); 242 secondaryText.setVisibility(View.VISIBLE); 243 layoutParam.height = LayoutParams.WRAP_CONTENT; 244 } else { 245 secondaryText.setVisibility(View.GONE); 246 layoutParam.height = LayoutParams.MATCH_PARENT; 247 } 248 249 calendarName.setLayoutParams(layoutParam); 250 251 } else { 252 // Tablet layout 253 RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( 254 SELECTED_COLOR_CHIP_SIZE, SELECTED_COLOR_CHIP_SIZE); 255 params.leftMargin = COLOR_CHIP_LEFT_MARGIN; 256 params.rightMargin = COLOR_CHIP_RIGHT_MARGIN; 257 // This offset is needed because the assets include the bottom of the 258 // previous item 259 params.topMargin = COLOR_CHIP_TOP_OFFSET; 260 if (!selected) { 261 params.height = UNSELECTED_COLOR_CHIP_SIZE; 262 params.width = UNSELECTED_COLOR_CHIP_SIZE; 263 params.leftMargin += (SELECTED_COLOR_CHIP_SIZE - UNSELECTED_COLOR_CHIP_SIZE) / 2; 264 params.topMargin += (SELECTED_COLOR_CHIP_SIZE - UNSELECTED_COLOR_CHIP_SIZE) / 2; 265 } 266 colorView.setLayoutParams(params); 267 268 Drawable bg = getBackground(position, selected); 269 view.setBackgroundDrawable(bg); 270 ViewGroup.LayoutParams newParams = view.getLayoutParams(); 271 if (position == mData.length - 1) { 272 newParams.height = BOTTOM_ITEM_HEIGHT; 273 } else { 274 newParams.height = NORMAL_ITEM_HEIGHT; 275 } 276 view.setLayoutParams(newParams); 277 } 278 view.invalidate(); 279 return view; 280 } 281 282 /** 283 * @param position position of the calendar item 284 * @param selected whether it is selected or not 285 * @return the drawable to use for this view 286 */ 287 protected Drawable getBackground(int position, boolean selected) { 288 int bg; 289 bg = selected ? IS_SELECTED : 0; 290 bg |= (position == 0 && mOrientation == Configuration.ORIENTATION_LANDSCAPE) ? IS_TOP : 0; 291 bg |= position == mData.length - 1 ? IS_BOTTOM : 0; 292 bg |= (position > 0 && mData[position - 1].selected) ? IS_BELOW_SELECTED : 0; 293 return mRes.getDrawable(TabletCalendarItemBackgrounds.getBackgrounds()[bg]); 294 } 295 296 private static void setText(View view, int id, String text) { 297 if (TextUtils.isEmpty(text)) { 298 return; 299 } 300 TextView textView = (TextView) view.findViewById(id); 301 textView.setText(text); 302 } 303 304 public int getCount() { 305 return mRowCount; 306 } 307 308 public Object getItem(int position) { 309 if (position >= mRowCount) { 310 return null; 311 } 312 CalendarRow item = mData[position]; 313 return item; 314 } 315 316 public long getItemId(int position) { 317 if (position >= mRowCount) { 318 return 0; 319 } 320 return mData[position].id; 321 } 322 323 public void setVisible(int position, int visible) { 324 mData[position].selected = visible != 0; 325 notifyDataSetChanged(); 326 } 327 328 public int getVisible(int position) { 329 return mData[position].selected ? 1 : 0; 330 } 331 332 @Override 333 public boolean hasStableIds() { 334 return true; 335 } 336} 337