1 /* 2 * Copyright (C) 2015 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.packageinstaller.permission.ui.wear.settings; 18 19 import android.content.Context; 20 import android.support.wearable.view.CircledImageView; 21 import android.support.wearable.view.WearableListView; 22 import android.util.Log; 23 import android.view.Gravity; 24 import android.view.View; 25 import android.view.ViewGroup; 26 import android.widget.FrameLayout; 27 import android.widget.TextView; 28 29 import com.android.packageinstaller.R; 30 31 import java.util.ArrayList; 32 33 /** 34 * Common adapter for settings views. Maintains a list of 'Settings', consisting of a name, 35 * icon and optional activity-specific data. 36 */ 37 public class SettingsAdapter<T> extends WearableListView.Adapter { 38 private static final String TAG = "SettingsAdapter"; 39 private final Context mContext; 40 41 public static final class Setting<S> { 42 public static final int ID_INVALID = -1; 43 44 public final int id; 45 public int nameResourceId; 46 public CharSequence name; 47 public int iconResource; 48 public boolean inProgress; 49 public S data; 50 Setting(CharSequence name, int iconResource, S data)51 public Setting(CharSequence name, int iconResource, S data) { 52 this(name, iconResource, data, ID_INVALID); 53 } 54 Setting(CharSequence name, int iconResource, S data, int id)55 public Setting(CharSequence name, int iconResource, S data, int id) { 56 this.name = name; 57 this.iconResource = iconResource; 58 this.data = data; 59 this.inProgress = false; 60 this.id = id; 61 } 62 Setting(int nameResource, int iconResource, S data, int id)63 public Setting(int nameResource, int iconResource, S data, int id) { 64 this.nameResourceId = nameResource; 65 this.iconResource = iconResource; 66 this.data = data; 67 this.inProgress = false; 68 this.id = id; 69 } 70 Setting(int nameResource, int iconResource, int id)71 public Setting(int nameResource, int iconResource, int id) { 72 this.nameResourceId = nameResource; 73 this.iconResource = iconResource; 74 this.data = null; 75 this.inProgress = false; 76 this.id = id; 77 } 78 Setting(CharSequence name, int iconResource, int id)79 public Setting(CharSequence name, int iconResource, int id) { 80 this(name, iconResource, null, id); 81 } 82 83 } 84 85 private final int mItemLayoutId; 86 private final float mDefaultCircleRadiusPercent; 87 private final float mSelectedCircleRadiusPercent; 88 89 protected ArrayList<Setting<T>> mSettings = new ArrayList<Setting<T>>(); 90 SettingsAdapter(Context context, int itemLayoutId)91 public SettingsAdapter(Context context, int itemLayoutId) { 92 mContext = context; 93 mItemLayoutId = itemLayoutId; 94 mDefaultCircleRadiusPercent = context.getResources().getFraction( 95 R.dimen.default_settings_circle_radius_percent, 1, 1); 96 mSelectedCircleRadiusPercent = context.getResources().getFraction( 97 R.dimen.selected_settings_circle_radius_percent, 1, 1); 98 } 99 100 @Override onCreateViewHolder(ViewGroup parent, int viewType)101 public WearableListView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 102 return new SettingsItemHolder(new SettingsItem(parent.getContext())); 103 } 104 105 @Override onBindViewHolder(WearableListView.ViewHolder holder, int position)106 public void onBindViewHolder(WearableListView.ViewHolder holder, int position) { 107 Setting<T> setting = mSettings.get(position); 108 if (setting.iconResource == -1) { 109 ((SettingsItemHolder) holder).imageView.setVisibility(View.GONE); 110 } else { 111 ((SettingsItemHolder) holder).imageView.setVisibility(View.VISIBLE); 112 ((SettingsItemHolder) holder).imageView.setImageResource( 113 mSettings.get(position).iconResource); 114 } 115 Log.d(TAG, "onBindViewHolder " + setting.name + " " + setting.id + " " + setting 116 .nameResourceId); 117 if (setting.name == null && setting.nameResourceId != 0) { 118 setting.name = mContext.getString(setting.nameResourceId); 119 } 120 ((SettingsItemHolder) holder).textView.setText(setting.name); 121 } 122 123 @Override getItemCount()124 public int getItemCount() { 125 return mSettings.size(); 126 } 127 addSetting(CharSequence name, int iconResource)128 public void addSetting(CharSequence name, int iconResource) { 129 addSetting(name, iconResource, null); 130 } 131 addSetting(CharSequence name, int iconResource, T intent)132 public void addSetting(CharSequence name, int iconResource, T intent) { 133 addSetting(mSettings.size(), name, iconResource, intent); 134 } 135 addSetting(int index, CharSequence name, int iconResource, T intent)136 public void addSetting(int index, CharSequence name, int iconResource, T intent) { 137 addSetting(Setting.ID_INVALID, index, name, iconResource, intent); 138 } 139 addSetting(int id, int index, CharSequence name, int iconResource, T intent)140 public void addSetting(int id, int index, CharSequence name, int iconResource, T intent) { 141 mSettings.add(index, new Setting<T>(name, iconResource, intent, id)); 142 notifyItemInserted(index); 143 } 144 addSettingDontNotify(Setting<T> setting)145 public void addSettingDontNotify(Setting<T> setting) { 146 mSettings.add(setting); 147 } 148 addSetting(Setting<T> setting)149 public void addSetting(Setting<T> setting) { 150 mSettings.add(setting); 151 notifyItemInserted(mSettings.size() - 1); 152 } 153 addSetting(int index, Setting<T> setting)154 public void addSetting(int index, Setting<T> setting) { 155 mSettings.add(index, setting); 156 notifyItemInserted(index); 157 } 158 159 /** 160 * Returns the index of the setting in the adapter based on the ID supplied when it was 161 * originally added. 162 * @param id the setting's id 163 * @return index in the adapter of the setting. -1 if not found. 164 */ findSetting(int id)165 public int findSetting(int id) { 166 for (int i = mSettings.size() - 1; i >= 0; --i) { 167 Setting setting = mSettings.get(i); 168 169 if (setting.id == id) { 170 return i; 171 } 172 } 173 174 return -1; 175 } 176 177 /** 178 * Removes a setting at the given index. 179 * @param index the index of the setting to be removed 180 */ removeSetting(int index)181 public void removeSetting(int index) { 182 mSettings.remove(index); 183 notifyDataSetChanged(); 184 } 185 clearSettings()186 public void clearSettings() { 187 mSettings.clear(); 188 notifyDataSetChanged(); 189 } 190 191 /** 192 * Updates a setting in place. 193 * @param index the index of the setting 194 * @param name the updated setting name 195 * @param iconResource the update setting icon 196 * @param intent the updated intent for the setting 197 */ updateSetting(int index, CharSequence name, int iconResource, T intent)198 public void updateSetting(int index, CharSequence name, int iconResource, T intent) { 199 Setting<T> setting = mSettings.get(index); 200 setting.iconResource = iconResource; 201 setting.name = name; 202 setting.data = intent; 203 notifyItemChanged(index); 204 } 205 get(int position)206 public Setting<T> get(int position) { 207 return mSettings.get(position); 208 } 209 210 protected static class SettingsItemHolder extends ExtendedViewHolder { 211 public final CircledImageView imageView; 212 public final TextView textView; 213 SettingsItemHolder(View itemView)214 public SettingsItemHolder(View itemView) { 215 super(itemView); 216 217 imageView = ((CircledImageView) itemView.findViewById(R.id.image)); 218 textView = ((TextView) itemView.findViewById(R.id.text)); 219 } 220 } 221 222 protected class SettingsItem extends FrameLayout implements ExtendedOnCenterProximityListener { 223 224 protected final CircledImageView mImage; 225 protected final TextView mText; 226 SettingsItem(Context context)227 public SettingsItem(Context context) { 228 super(context); 229 View view = View.inflate(context, mItemLayoutId, null); 230 FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( 231 FrameLayout.LayoutParams.MATCH_PARENT, 232 FrameLayout.LayoutParams.MATCH_PARENT); 233 params.gravity = Gravity.CENTER_VERTICAL; 234 addView(view, params); 235 mImage = (CircledImageView) findViewById(R.id.image); 236 mText = (TextView) findViewById(R.id.text); 237 } 238 239 @Override getProximityMinValue()240 public float getProximityMinValue() { 241 return mDefaultCircleRadiusPercent; 242 } 243 244 @Override getProximityMaxValue()245 public float getProximityMaxValue() { 246 return mSelectedCircleRadiusPercent; 247 } 248 249 @Override getCurrentProximityValue()250 public float getCurrentProximityValue() { 251 return mImage.getCircleRadiusPressedPercent(); 252 } 253 254 @Override setScalingAnimatorValue(float value)255 public void setScalingAnimatorValue(float value) { 256 mImage.setCircleRadiusPercent(value); 257 mImage.setCircleRadiusPressedPercent(value); 258 } 259 260 @Override onCenterPosition(boolean animate)261 public void onCenterPosition(boolean animate) { 262 mImage.setAlpha(1f); 263 mText.setAlpha(1f); 264 } 265 266 @Override onNonCenterPosition(boolean animate)267 public void onNonCenterPosition(boolean animate) { 268 mImage.setAlpha(0.5f); 269 mText.setAlpha(0.5f); 270 } 271 getTextView()272 TextView getTextView() { 273 return mText; 274 } 275 } 276 } 277