1 /* 2 * Copyright (C) 2014 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.tv.settings.dialog.old; 18 19 import android.animation.ObjectAnimator; 20 import android.app.Activity; 21 import android.content.Context; 22 import android.graphics.Bitmap; 23 import android.graphics.Color; 24 import android.graphics.drawable.Drawable; 25 import android.net.Uri; 26 import android.os.Bundle; 27 import android.view.accessibility.AccessibilityManager; 28 import android.view.LayoutInflater; 29 import android.view.View; 30 import android.view.ViewGroup; 31 import android.view.ViewGroup.LayoutParams; 32 import android.widget.ImageView; 33 import android.widget.RelativeLayout; 34 import android.widget.TextView; 35 36 import com.android.tv.settings.R; 37 import com.android.tv.settings.widget.BitmapDownloader; 38 import com.android.tv.settings.widget.BitmapDownloader.BitmapCallback; 39 import com.android.tv.settings.widget.BitmapWorkerOptions; 40 import com.android.tv.settings.widget.FrameLayoutWithShadows; 41 42 /** 43 * This class exists to make extending both v4 fragments and regular fragments easy 44 */ 45 public class BaseContentFragment { 46 47 private static final String EXTRA_TITLE = "title"; 48 private static final String EXTRA_BREADCRUMB = "breadcrumb"; 49 private static final String EXTRA_DESCRIPTION = "description"; 50 private static final String EXTRA_ICON_RESOURCE_ID = "iconResourceId"; 51 private static final String EXTRA_ICON_URI = "iconUri"; 52 private static final String EXTRA_ICON_BITMAP = "iconBitmap"; 53 private static final String EXTRA_ICON_BACKGROUND = "iconBackground"; 54 55 public static Bundle buildArgs( 56 String title, String breadcrumb, String description, int iconResourceId, 57 int backgroundColor) { 58 return buildArgs(title, breadcrumb, description, iconResourceId, null, null, 59 backgroundColor); 60 } 61 62 public static Bundle buildArgs(String title, String breadcrumb, String description, Uri iconUri, 63 int backgroundColor) { 64 return buildArgs(title, breadcrumb, description, 0, iconUri, null, backgroundColor); 65 } 66 67 public static Bundle buildArgs(String title, String breadcrumb, String description, 68 Bitmap iconBitmap) { 69 return buildArgs(title, breadcrumb, description, 0, null, iconBitmap, Color.TRANSPARENT); 70 } 71 72 private static Bundle buildArgs( 73 String title, String breadcrumb, String description, int iconResourceId, 74 Uri iconUri, Bitmap iconBitmap, int iconBackgroundColor) { 75 Bundle args = new Bundle(); 76 args.putString(EXTRA_TITLE, title); 77 args.putString(EXTRA_BREADCRUMB, breadcrumb); 78 args.putString(EXTRA_DESCRIPTION, description); 79 args.putInt(EXTRA_ICON_RESOURCE_ID, iconResourceId); 80 args.putParcelable(EXTRA_ICON_URI, iconUri); 81 args.putParcelable(EXTRA_ICON_BITMAP, iconBitmap); 82 args.putInt(EXTRA_ICON_BACKGROUND, iconBackgroundColor); 83 return args; 84 } 85 86 private final LiteFragment mFragment; 87 private Activity mActivity; 88 private BitmapCallback mBitmapCallBack; 89 private String mTitle; 90 private String mBreadcrumb; 91 private String mDescription; 92 private int mIconResourceId; 93 private Uri mIconUri; 94 private Bitmap mIconBitmap; 95 private int mIconBackgroundColor; 96 private AccessibilityManager mAccessManager; 97 98 public BaseContentFragment(LiteFragment fragment) { 99 mFragment = fragment; 100 } 101 102 public void onCreate(Bundle savedInstanceState) { 103 Bundle state = (savedInstanceState != null) ? savedInstanceState : mFragment.getArguments(); 104 if (mTitle == null) { 105 mTitle = state.getString(EXTRA_TITLE); 106 } 107 if (mBreadcrumb == null) { 108 mBreadcrumb = state.getString(EXTRA_BREADCRUMB); 109 } 110 if (mDescription == null) { 111 mDescription = state.getString(EXTRA_DESCRIPTION); 112 } 113 if (mIconResourceId == 0) { 114 mIconResourceId = state.getInt(EXTRA_ICON_RESOURCE_ID, 0); 115 } 116 if (mIconUri == null) { 117 mIconUri = state.getParcelable(EXTRA_ICON_URI); 118 } 119 if (mIconBitmap == null) { 120 mIconBitmap = state.getParcelable(EXTRA_ICON_BITMAP); 121 } 122 if (mIconBackgroundColor == Color.TRANSPARENT) { 123 mIconBackgroundColor = state.getInt(EXTRA_ICON_BACKGROUND, Color.TRANSPARENT); 124 } 125 } 126 127 public void onSaveInstanceState(Bundle outState) { 128 outState.putString(EXTRA_TITLE, mTitle); 129 outState.putString(EXTRA_BREADCRUMB, mBreadcrumb); 130 outState.putString(EXTRA_DESCRIPTION, mDescription); 131 outState.putInt(EXTRA_ICON_RESOURCE_ID, mIconResourceId); 132 outState.putParcelable(EXTRA_ICON_URI, mIconUri); 133 outState.putParcelable(EXTRA_ICON_BITMAP, mIconBitmap); 134 outState.putInt(EXTRA_ICON_BACKGROUND, mIconBackgroundColor); 135 } 136 137 /** 138 * Pass activity from ContentFragment to BaseContentFragment when it is 139 * attached. 140 */ 141 public void onAttach(Activity activity) { 142 mActivity = activity; 143 } 144 145 /** 146 * Rest BaseContentFragment mActivity to null when ContentFragment is 147 * detached. 148 */ 149 public void onDetach() { 150 mActivity = null; 151 } 152 153 /** 154 * When ContentFragment is winding down / being destroyed, if the 155 * BitmapDownloader is still getting Bitmap for icon ImageView, we should 156 * cancel it. 157 */ 158 public void onDestroyView() { 159 if (mActivity != null 160 && mBitmapCallBack != null) { 161 BitmapDownloader bitmapDownloader = BitmapDownloader.getInstance(mActivity); 162 bitmapDownloader.cancelDownload(mBitmapCallBack); 163 } 164 } 165 166 public View onCreateView( 167 LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 168 final View view = inflater.inflate(R.layout.content_fragment, container, false); 169 setText(view, R.id.title, mTitle); 170 setText(view, R.id.breadcrumb, mBreadcrumb); 171 setText(view, R.id.description, mDescription); 172 int iconResourceId = getIconResourceId(); 173 final ImageView iconImageView = (ImageView) view.findViewById(R.id.icon); 174 int iconBackground = getIconBackgroundColor(); 175 if (iconBackground != Color.TRANSPARENT) { 176 iconImageView.setBackgroundColor(iconBackground); 177 } 178 179 if (iconResourceId != 0) { 180 iconImageView.setImageResource(iconResourceId); 181 addShadow(iconImageView, view); 182 updateViewSize(iconImageView); 183 } else { 184 Bitmap iconBitmap = getIconBitmap(); 185 if (iconBitmap != null) { 186 iconImageView.setImageBitmap(iconBitmap); 187 addShadow(iconImageView, view); 188 updateViewSize(iconImageView); 189 } else { 190 Uri iconUri = getIconResourceUri(); 191 if (iconUri != null) { 192 iconImageView.setVisibility(View.INVISIBLE); 193 194 if (mActivity != null) { 195 BitmapDownloader bitmapDownloader = BitmapDownloader.getInstance(mActivity); 196 mBitmapCallBack = new BitmapCallback() { 197 @Override 198 public void onBitmapRetrieved(Bitmap bitmap) { 199 if (bitmap != null) { 200 mIconBitmap = bitmap; 201 iconImageView.setVisibility(View.VISIBLE); 202 iconImageView.setImageBitmap(bitmap); 203 addShadow(iconImageView, view); 204 updateViewSize(iconImageView); 205 } 206 } 207 }; 208 209 bitmapDownloader.getBitmap(new BitmapWorkerOptions.Builder( 210 mActivity).resource(iconUri) 211 .width(iconImageView.getLayoutParams().width).build(), 212 mBitmapCallBack); 213 } 214 } else { 215 iconImageView.setVisibility(View.GONE); 216 } 217 } 218 } 219 220 return view; 221 } 222 223 public ImageView getIcon() { 224 if (mFragment.getView() == null) return null; 225 return (ImageView) mFragment.getView().findViewById(R.id.icon); 226 } 227 228 public TextView getTitle() { 229 if (mFragment.getView() == null) return null; 230 return (TextView) mFragment.getView().findViewById(R.id.title); 231 } 232 233 public Uri getIconResourceUri() { 234 return mIconUri; 235 } 236 237 public int getIconResourceId() { 238 return mIconResourceId; 239 } 240 241 public Bitmap getIconBitmap() { 242 return mIconBitmap; 243 } 244 245 public int getIconBackgroundColor() { 246 return mIconBackgroundColor; 247 } 248 249 public RelativeLayout getRoot() { 250 return (RelativeLayout) mFragment.getView(); 251 } 252 253 public TextView getBreadCrumb() { 254 if (mFragment.getView() == null) return null; 255 return (TextView) mFragment.getView().findViewById(R.id.breadcrumb); 256 } 257 258 public TextView getDescription() { 259 if (mFragment.getView() == null) return null; 260 return (TextView) mFragment.getView().findViewById(R.id.description); 261 } 262 263 public void setTextToExtra(View parent, int textViewResourceId, 264 String extraLabel) { 265 String text = mFragment.getArguments().getString(extraLabel, null); 266 setText(parent, textViewResourceId, text); 267 } 268 269 public void setTextToExtra(int textViewResourceId, String extraLabel) { 270 if (mFragment.getView() == null) return; 271 setTextToExtra(mFragment.getView(), textViewResourceId, extraLabel); 272 } 273 274 public void setText(View parent, int textViewResourceId, String text) { 275 TextView textView = (TextView) parent.findViewById(textViewResourceId); 276 if (textView != null && text != null) { 277 textView.setText(text); 278 279 // Enable focusable title and description if accessibility is enabled. 280 if (mActivity != null) { 281 if (mAccessManager == null) { 282 mAccessManager = (AccessibilityManager) mActivity 283 .getSystemService(Context.ACCESSIBILITY_SERVICE); 284 } 285 if (mAccessManager.isEnabled()) { 286 textView.setFocusable(true); 287 textView.setFocusableInTouchMode(true); 288 } 289 } 290 } 291 } 292 293 public void setText(int textViewResourceId, String text) { 294 if (mFragment.getView() == null) return; 295 setText(mFragment.getView(), textViewResourceId, text); 296 } 297 298 public void setTitleText(String text) { 299 mTitle = text; 300 if (mFragment.getView() == null) return; 301 setText(mFragment.getView(), R.id.title, text); 302 } 303 304 public void setBreadCrumbText(String text) { 305 mBreadcrumb = text; 306 if (mFragment.getView() == null) return; 307 setText(mFragment.getView(), R.id.breadcrumb, text); 308 } 309 310 public void setDescriptionText(String text) { 311 mDescription = text; 312 if (mFragment.getView() == null) return; 313 setText(mFragment.getView(), R.id.description, text); 314 } 315 316 /** 317 * Unlike {@link #setIcon(int)} and {@link #setIcon(Uri)}, this will only work if called 318 * after {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}. 319 * @param iconDrawable 320 */ 321 public void setIcon(Drawable iconDrawable) { 322 if (mFragment.getView() == null) return; 323 324 final ImageView iconImageView = (ImageView) mFragment.getView().findViewById(R.id.icon); 325 if (iconImageView != null) { 326 if (iconDrawable != null) { 327 iconImageView.setImageDrawable(iconDrawable); 328 iconImageView.setVisibility(View.VISIBLE); 329 updateViewSize(iconImageView); 330 } 331 } 332 } 333 334 public void setIcon(int iconResourceId) { 335 mIconResourceId = iconResourceId; 336 if (mFragment.getView() == null) return; 337 338 final ImageView iconImageView = (ImageView) mFragment.getView().findViewById(R.id.icon); 339 if (iconImageView != null) { 340 if (iconResourceId != 0) { 341 iconImageView.setImageResource(iconResourceId); 342 iconImageView.setVisibility(View.VISIBLE); 343 updateViewSize(iconImageView); 344 } 345 } 346 } 347 348 public void setIcon(Uri iconUri) { 349 mIconUri = iconUri; 350 if (mFragment.getView() == null) return; 351 352 final ImageView iconImageView = (ImageView) mFragment.getView().findViewById(R.id.icon); 353 if (iconImageView != null) { 354 if (iconUri != null) { 355 iconImageView.setVisibility(View.INVISIBLE); 356 357 if (mActivity != null) { 358 BitmapDownloader bitmapDownloader = BitmapDownloader.getInstance(mActivity); 359 mBitmapCallBack = new BitmapCallback() { 360 @Override 361 public void onBitmapRetrieved(Bitmap bitmap) { 362 if (bitmap != null) { 363 mIconBitmap = bitmap; 364 iconImageView.setImageBitmap(bitmap); 365 iconImageView.setVisibility(View.VISIBLE); 366 updateViewSize(iconImageView); 367 fadeIn(iconImageView); 368 addShadow(iconImageView, mFragment.getView()); 369 } 370 } 371 }; 372 373 bitmapDownloader.getBitmap(new BitmapWorkerOptions.Builder(mActivity).resource( 374 iconUri).width(iconImageView.getLayoutParams().width).build(), 375 mBitmapCallBack); 376 } 377 } 378 } 379 } 380 381 private void updateViewSize(ImageView iconView) { 382 int intrinsicWidth = iconView.getDrawable().getIntrinsicWidth(); 383 LayoutParams lp = iconView.getLayoutParams(); 384 if (intrinsicWidth > 0) { 385 lp.height = lp.width * iconView.getDrawable().getIntrinsicHeight() 386 / intrinsicWidth; 387 } else { 388 // If no intrinsic width, then just mke this a square. 389 lp.height = lp.width; 390 } 391 } 392 393 private void addShadow(ImageView icon, View view) { 394 FrameLayoutWithShadows shadowLayout = (FrameLayoutWithShadows) 395 view.findViewById(R.id.shadow_layout); 396 shadowLayout.addShadowView(icon); 397 } 398 399 private void fadeIn(View v) { 400 v.setAlpha(0f); 401 ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(v, "alpha", 1f); 402 alphaAnimator.setDuration(mActivity.getResources().getInteger( 403 android.R.integer.config_mediumAnimTime)); 404 alphaAnimator.start(); 405 } 406 } 407