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