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