• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package android.support.v17.leanback.widget;
2 
3 import android.support.v17.leanback.R;
4 
5 import android.graphics.drawable.Drawable;
6 import android.view.LayoutInflater;
7 import android.view.View;
8 import android.view.ViewGroup;
9 import android.view.ViewGroup.MarginLayoutParams;
10 import android.widget.ImageView;
11 
12 /**
13  * Presenter that responsible to create a ImageView and bind to DetailsOverviewRow. The default
14  * implementation uses {@link DetailsOverviewRow#getImageDrawable()} and binds to {@link ImageView}.
15  * <p>
16  * Default implementation assumes no scaleType on ImageView and uses intrinsic width and height of
17  * {@link DetailsOverviewRow#getImageDrawable()} to initialize ImageView's layout params.  To
18  * specify a fixed size and/or specify a scapeType, subclass should change ImageView's layout params
19  * and scaleType in {@link #onCreateView(ViewGroup)}.
20  * <p>
21  * Subclass may override and has its own image view. Subclass may also download image from URL
22  * instead of using {@link DetailsOverviewRow#getImageDrawable()}. It's subclass's responsibility to
23  * call {@link FullWidthDetailsOverviewRowPresenter#notifyOnBindLogo(FullWidthDetailsOverviewRowPresenter.ViewHolder)}
24  * whenever {@link #isBoundToImage(ViewHolder, DetailsOverviewRow)} turned to true so that activity
25  * transition can be started.
26  */
27 public class DetailsOverviewLogoPresenter extends Presenter {
28 
29     /**
30      * ViewHolder for Logo view of DetailsOverviewRow.
31      */
32     public static class ViewHolder extends Presenter.ViewHolder {
33 
34         protected FullWidthDetailsOverviewRowPresenter mParentPresenter;
35         protected FullWidthDetailsOverviewRowPresenter.ViewHolder mParentViewHolder;
36         private boolean mSizeFromDrawableIntrinsic;
37 
ViewHolder(View view)38         public ViewHolder(View view) {
39             super(view);
40         }
41 
getParentPresenter()42         public FullWidthDetailsOverviewRowPresenter getParentPresenter() {
43             return mParentPresenter;
44         }
45 
getParentViewHolder()46         public FullWidthDetailsOverviewRowPresenter.ViewHolder getParentViewHolder() {
47             return mParentViewHolder;
48         }
49 
50         /**
51          * @return True if layout size of ImageView should be changed to intrinsic size of Drawable,
52          *         false otherwise. Used by
53          *         {@link DetailsOverviewLogoPresenter#onBindViewHolder(Presenter.ViewHolder, Object)}
54          *         .
55          *
56          * @see DetailsOverviewLogoPresenter#onCreateView(ViewGroup)
57          * @see DetailsOverviewLogoPresenter#onBindViewHolder(Presenter.ViewHolder, Object)
58          */
isSizeFromDrawableIntrinsic()59         public boolean isSizeFromDrawableIntrinsic() {
60             return mSizeFromDrawableIntrinsic;
61         }
62 
63         /**
64          * Change if the ImageView layout size should be synchronized to Drawable intrinsic size.
65          * Used by
66          * {@link DetailsOverviewLogoPresenter#onBindViewHolder(Presenter.ViewHolder, Object)}.
67          *
68          * @param sizeFromDrawableIntrinsic True if layout size of ImageView should be changed to
69          *        intrinsic size of Drawable, false otherwise.
70          *
71          * @see DetailsOverviewLogoPresenter#onCreateView(ViewGroup)
72          * @see DetailsOverviewLogoPresenter#onBindViewHolder(Presenter.ViewHolder, Object)
73          */
setSizeFromDrawableIntrinsic(boolean sizeFromDrawableIntrinsic)74         public void setSizeFromDrawableIntrinsic(boolean sizeFromDrawableIntrinsic) {
75             mSizeFromDrawableIntrinsic = sizeFromDrawableIntrinsic;
76         }
77     }
78 
79     /**
80      * Create a View for the Logo, default implementation loads from
81      * {@link R.layout#lb_fullwidth_details_overview_logo}. Subclass may override this method to use
82      * a fixed layout size and change ImageView scaleType. If the layout params is WRAP_CONTENT for
83      * both width and size, the ViewHolder would be using intrinsic size of Drawable in
84      * {@link #onBindViewHolder(Presenter.ViewHolder, Object)}.
85      *
86      * @param parent Parent view.
87      * @return View created for the logo.
88      */
onCreateView(ViewGroup parent)89     public View onCreateView(ViewGroup parent) {
90         return LayoutInflater.from(parent.getContext())
91                 .inflate(R.layout.lb_fullwidth_details_overview_logo, parent, false);
92     }
93 
94     @Override
onCreateViewHolder(ViewGroup parent)95     public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) {
96         View view = onCreateView(parent);
97         ViewHolder vh = new ViewHolder(view);
98         ViewGroup.LayoutParams lp = view.getLayoutParams();
99         vh.setSizeFromDrawableIntrinsic(lp.width == ViewGroup.LayoutParams.WRAP_CONTENT &&
100                 lp.width == ViewGroup.LayoutParams.WRAP_CONTENT);
101         return vh;
102     }
103 
104     /**
105      * Called from {@link FullWidthDetailsOverviewRowPresenter} to setup FullWidthDetailsOverviewRowPresenter
106      * and FullWidthDetailsOverviewRowPresenter.ViewHolder that hosts the logo.
107      * @param viewHolder
108      * @param parentViewHolder
109      * @param parentPresenter
110      */
setContext(ViewHolder viewHolder, FullWidthDetailsOverviewRowPresenter.ViewHolder parentViewHolder, FullWidthDetailsOverviewRowPresenter parentPresenter)111     public void setContext(ViewHolder viewHolder,
112             FullWidthDetailsOverviewRowPresenter.ViewHolder parentViewHolder,
113             FullWidthDetailsOverviewRowPresenter parentPresenter) {
114         viewHolder.mParentViewHolder = parentViewHolder;
115         viewHolder.mParentPresenter = parentPresenter;
116     }
117 
118     /**
119      * Returns true if the logo view is bound to image. Subclass may override. The default
120      * implementation returns true when {@link DetailsOverviewRow#getImageDrawable()} is not null.
121      * If subclass of DetailsOverviewLogoPresenter manages its own image drawable, it should
122      * override this function to report status correctly and invoke
123      * {@link FullWidthDetailsOverviewRowPresenter#notifyOnBindLogo(FullWidthDetailsOverviewRowPresenter.ViewHolder)}
124      * when image view is bound to the drawable.
125      */
isBoundToImage(ViewHolder viewHolder, DetailsOverviewRow row)126     public boolean isBoundToImage(ViewHolder viewHolder, DetailsOverviewRow row) {
127         return row != null && row.getImageDrawable() != null;
128     }
129 
130     /**
131      * Bind logo View to drawable of DetailsOverviewRow and call notifyOnBindLogo().  The
132      * default implementation assumes the Logo View is an ImageView and change layout size to
133      * intrinsic size of ImageDrawable if {@link ViewHolder#isSizeFromDrawableIntrinsic()} is true.
134      * @param viewHolder ViewHolder to bind.
135      * @param item DetailsOverviewRow object to bind.
136      */
137     @Override
onBindViewHolder(Presenter.ViewHolder viewHolder, Object item)138     public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
139         DetailsOverviewRow row = (DetailsOverviewRow) item;
140         ImageView imageView = ((ImageView) viewHolder.view);
141         imageView.setImageDrawable(row.getImageDrawable());
142         if (isBoundToImage((ViewHolder) viewHolder, row)) {
143             ViewHolder vh = (ViewHolder) viewHolder;
144             if (vh.isSizeFromDrawableIntrinsic()) {
145                 ViewGroup.LayoutParams lp = imageView.getLayoutParams();
146                 lp.width = row.getImageDrawable().getIntrinsicWidth();
147                 lp.height = row.getImageDrawable().getIntrinsicHeight();
148                 if (imageView.getMaxWidth() > 0 || imageView.getMaxHeight() > 0) {
149                     float maxScaleWidth = 1f;
150                     if (imageView.getMaxWidth() > 0) {
151                         if (lp.width > imageView.getMaxWidth()) {
152                             maxScaleWidth = imageView.getMaxWidth() / (float) lp.width;
153                         }
154                     }
155                     float maxScaleHeight = 1f;
156                     if (imageView.getMaxHeight() > 0) {
157                         if (lp.height > imageView.getMaxHeight()) {
158                             maxScaleHeight = imageView.getMaxHeight() / (float) lp.height;
159                         }
160                     }
161                     float scale = Math.min(maxScaleWidth, maxScaleHeight);
162                     lp.width = (int) (lp.width * scale);
163                     lp.height = (int) (lp.height * scale);
164                 }
165                 imageView.setLayoutParams(lp);
166             }
167             vh.mParentPresenter.notifyOnBindLogo(vh.mParentViewHolder);
168         }
169     }
170 
171     @Override
onUnbindViewHolder(Presenter.ViewHolder viewHolder)172     public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
173     }
174 
175 }
176