DigitalWidgetViewsFactory.java revision 3bb9d29c12584480f3651ccbef86f2777c0b7818
1/* 2 * Copyright (C) 2012 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.alarmclock; 18 19import android.appwidget.AppWidgetManager; 20import android.content.Context; 21import android.content.Intent; 22import android.text.format.DateFormat; 23import android.util.Log; 24import android.util.TypedValue; 25import android.view.View; 26import android.widget.RemoteViews; 27import android.widget.RemoteViewsService.RemoteViewsFactory; 28 29import com.android.deskclock.R; 30import com.android.deskclock.Utils; 31import com.android.deskclock.worldclock.CityObj; 32import com.android.deskclock.worldclock.WorldClockAdapter; 33 34import java.util.Calendar; 35import java.util.Locale; 36import java.util.TimeZone; 37 38public class DigitalWidgetViewsFactory implements RemoteViewsFactory { 39 private static final String TAG = "DigitalWidgetViewsFactory"; 40 41 private Context mContext; 42 private int mId = AppWidgetManager.INVALID_APPWIDGET_ID; 43 private RemoteWorldClockAdapter mAdapter; 44 private float mFontScale = 1; 45 46 // An adapter to provide the view for the list of cities in the world clock. 47 private class RemoteWorldClockAdapter extends WorldClockAdapter { 48 private final float mFontSize; 49 private final float mFont24Size; 50 51 public RemoteWorldClockAdapter(Context context) { 52 super(context); 53 mFontSize = context.getResources().getDimension(R.dimen.widget_medium_font_size); 54 mFont24Size = context.getResources().getDimension(R.dimen.widget_24_medium_font_size); 55 } 56 57 public RemoteViews getViewAt(int position) { 58 // There are 2 cities per item 59 int index = position * 2; 60 if (index < 0 || index >= mCitiesList.length) { 61 return null; 62 } 63 64 RemoteViews views = new RemoteViews( 65 mContext.getPackageName(), R.layout.world_clock_remote_list_item); 66 67 // Always how the left clock 68 updateView(views, (CityObj) mCitiesList[index], R.id.leftClock1, R.id.leftClock2, 69 R.id.city_name_left, R.id.city_day_left); 70 // Show the right clock if any, make it invisible if there is no 71 // clock on the right 72 // to keep the left view on the left. 73 if (index + 1 < mCitiesList.length) { 74 updateView(views, (CityObj) mCitiesList[index + 1], R.id.rightClock1, 75 R.id.rightClock2, R.id.city_name_right, R.id.city_day_right); 76 } else { 77 hideView(views, R.id.rightClock1, R.id.rightClock2, R.id.city_name_right, 78 R.id.city_day_right); 79 } 80 81 // Hide last spacer if last row 82 int lastRow = ((mCitiesList.length + 1) / 2) - 1; 83 if (position == lastRow) { 84 views.setViewVisibility(R.id.city_spacer, View.GONE); 85 } else { 86 views.setViewVisibility(R.id.city_spacer, View.VISIBLE); 87 } 88 89 return views; 90 } 91 92 private void updateView(RemoteViews clock, CityObj cityObj, int clockId1, int clockId2, 93 int labelId, int dayId) { 94 final Calendar now = Calendar.getInstance(); 95 now.setTimeInMillis(System.currentTimeMillis()); 96 int myDayOfWeek = now.get(Calendar.DAY_OF_WEEK); 97 CityObj cityInDb = mCitiesDb.get(cityObj.mCityId); 98 String cityTZ = (cityInDb != null) ? cityInDb.mTimeZone : cityObj.mTimeZone; 99 now.setTimeZone(TimeZone.getTimeZone(cityTZ)); 100 int cityDayOfWeek = now.get(Calendar.DAY_OF_WEEK); 101 102 float fontSize = mFontScale * (DateFormat.is24HourFormat(mContext) 103 ? mFont24Size : mFontSize); 104 clock.setTextViewTextSize(clockId1, TypedValue.COMPLEX_UNIT_PX, fontSize * mFontScale); 105 clock.setTextViewTextSize(clockId2, TypedValue.COMPLEX_UNIT_PX, fontSize * mFontScale); 106 clock.setString(clockId1, "setTimeZone", cityObj.mTimeZone); 107 clock.setString(clockId2, "setTimeZone", cityObj.mTimeZone); 108 109 // Home city or city not in DB , use data from the save selected cities list 110 clock.setTextViewText(labelId, Utils.getCityName(cityObj, cityInDb)); 111 112 if (myDayOfWeek != cityDayOfWeek) { 113 clock.setTextViewText(dayId, mContext.getString( 114 R.string.world_day_of_week_label, now.getDisplayName( 115 Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.getDefault()))); 116 clock.setViewVisibility(dayId, View.VISIBLE); 117 } else { 118 clock.setViewVisibility(dayId, View.GONE); 119 } 120 121 clock.setViewVisibility(clockId1, View.VISIBLE); 122 clock.setViewVisibility(clockId2, View.VISIBLE); 123 clock.setViewVisibility(labelId, View.VISIBLE); 124 } 125 126 private void hideView( 127 RemoteViews clock, int clockId1, int clockId2, int labelId, int dayId) { 128 clock.setViewVisibility(clockId1, View.INVISIBLE); 129 clock.setViewVisibility(clockId2, View.INVISIBLE); 130 clock.setViewVisibility(labelId, View.INVISIBLE); 131 clock.setViewVisibility(dayId, View.INVISIBLE); 132 } 133 } 134 135 public DigitalWidgetViewsFactory(Context context, Intent intent) { 136 mContext = context; 137 mId = intent.getIntExtra( 138 AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); 139 mAdapter = new RemoteWorldClockAdapter(context); 140 } 141 142 @SuppressWarnings("unused") 143 public DigitalWidgetViewsFactory() { 144 } 145 146 @Override 147 public int getCount() { 148 if (WidgetUtils.showList(mContext, mId, mFontScale)) { 149 return mAdapter.getCount(); 150 } 151 return 0; 152 } 153 154 @Override 155 public long getItemId(int position) { 156 return position; 157 } 158 159 @Override 160 public RemoteViews getLoadingView() { 161 return null; 162 } 163 164 @Override 165 public RemoteViews getViewAt(int position) { 166 RemoteViews v = mAdapter.getViewAt(position); 167 if (v != null) { 168 Intent fillInIntent = new Intent(); 169 v.setOnClickFillInIntent(R.id.widget_item, fillInIntent); 170 } 171 return v; 172 } 173 174 @Override 175 public int getViewTypeCount() { 176 return 1; 177 } 178 179 @Override 180 public boolean hasStableIds() { 181 return true; 182 } 183 184 @Override 185 public void onCreate() { 186 if (DigitalAppWidgetService.LOGGING) { 187 Log.i(TAG, "DigitalWidget onCreate " + mId); 188 } 189 } 190 191 @Override 192 public void onDataSetChanged() { 193 mAdapter.loadData(mContext); 194 mAdapter.loadCitiesDb(mContext); 195 mAdapter.updateHomeLabel(mContext); 196 197 mFontScale = WidgetUtils.getScaleRatio(mContext, null, mId); 198 } 199 200 @Override 201 public void onDestroy() { 202 if (DigitalAppWidgetService.LOGGING) { 203 Log.i(TAG, "DigitalWidget onDestroy " + mId); 204 } 205 } 206} 207 208