1package android.support.v17.leanback.widget; 2 3import android.support.v17.leanback.R; 4 5import android.graphics.drawable.Drawable; 6import android.view.LayoutInflater; 7import android.view.View; 8import android.view.ViewGroup; 9import android.view.ViewGroup.MarginLayoutParams; 10import 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 */ 27public 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 38 public ViewHolder(View view) { 39 super(view); 40 } 41 42 public FullWidthDetailsOverviewRowPresenter getParentPresenter() { 43 return mParentPresenter; 44 } 45 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 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 172 public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) { 173 } 174 175} 176