DetailsOverviewRowPresenter.java revision 2e0c922430f8c285b4325da52d69c09451069c93
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14package android.support.v17.leanback.widget; 15 16import android.content.Context; 17import android.graphics.Color; 18import android.support.v17.leanback.R; 19import android.support.v7.widget.RecyclerView; 20import android.util.Log; 21import android.util.TypedValue; 22import android.view.LayoutInflater; 23import android.view.View; 24import android.view.ViewGroup; 25import android.widget.FrameLayout; 26import android.widget.ImageView; 27 28import java.util.Collection; 29 30/** 31 * DetailsOverviewRowPresenter renders {@link DetailsOverviewRow} to display an 32 * overview of an item. Typically this row will be the first row in a fragment 33 * such as {@link android.support.v17.leanback.app.DetailsFragment 34 * DetailsFragment}. 35 * 36 * <p>The detailed description is rendered using a {@link Presenter}. 37 */ 38public class DetailsOverviewRowPresenter extends RowPresenter { 39 40 private static final String TAG = "DetailsOverviewRowPresenter"; 41 private static final boolean DEBUG = false; 42 43 private static final int MORE_ACTIONS_FADE_MS = 100; 44 45 public static class ViewHolder extends RowPresenter.ViewHolder { 46 final ImageView mImageView; 47 final FrameLayout mDetailsDescriptionFrame; 48 final HorizontalGridView mActionsRow; 49 final View mMoreActionsView; 50 Presenter.ViewHolder mDetailsDescriptionViewHolder; 51 52 class ScrollListener implements RecyclerView.OnScrollListener { 53 ObjectAdapter mAdapter; 54 boolean mShowMoreRight; 55 boolean mShowMoreLeft; 56 57 void bind(ObjectAdapter adapter) { 58 mAdapter = adapter; 59 60 mMoreActionsView.setAlpha(0f); 61 mShowMoreRight = false; 62 showMoreRight(true); 63 64 mShowMoreLeft = true; 65 showMoreLeft(false); 66 } 67 68 @Override 69 public void onScrollStateChanged(int newState) { 70 } 71 72 @Override 73 public void onScrolled(int dx, int dy) { 74 View view; 75 int position; 76 77 view = mActionsRow.getChildAt(mActionsRow.getChildCount() - 1); 78 position = mActionsRow.getChildViewHolder(view).getPosition(); 79 if (position < (mAdapter.size() - 1) || view.getRight() > mActionsRow.getWidth()) { 80 showMoreRight(true); 81 } else { 82 showMoreRight(false); 83 } 84 85 view = mActionsRow.getChildAt(0); 86 position = mActionsRow.getChildViewHolder(view).getPosition(); 87 if (position != 0 || view.getLeft() < 0) { 88 showMoreLeft(true); 89 } else { 90 showMoreLeft(false); 91 } 92 } 93 94 private void showMoreLeft(boolean show) { 95 if (show != mShowMoreLeft) { 96 mActionsRow.setFadingLeftEdge(show); 97 mShowMoreLeft = show; 98 } 99 } 100 101 private void showMoreRight(boolean show) { 102 if (show != mShowMoreRight) { 103 mMoreActionsView.animate().alpha(show ? 1f : 0).setDuration( 104 MORE_ACTIONS_FADE_MS).start(); 105 mActionsRow.setFadingRightEdge(show); 106 mShowMoreRight = show; 107 } 108 } 109 } 110 111 final ScrollListener mScrollListener = new ScrollListener(); 112 113 public ViewHolder(View rootView) { 114 super(rootView); 115 mImageView = (ImageView) rootView.findViewById(R.id.details_overview_image); 116 mDetailsDescriptionFrame = 117 (FrameLayout) rootView.findViewById(R.id.details_overview_description); 118 mActionsRow = 119 (HorizontalGridView) rootView.findViewById(R.id.details_overview_actions); 120 mActionsRow.setOnScrollListener(mScrollListener); 121 122 final int fadeLength = rootView.getResources().getDimensionPixelSize( 123 R.dimen.lb_details_overview_actions_fade_size); 124 mActionsRow.setFadingRightEdgeLength(fadeLength); 125 mActionsRow.setFadingRightEdgeOffset(-fadeLength); 126 mActionsRow.setFadingLeftEdgeLength(fadeLength); 127 mActionsRow.setFadingLeftEdgeOffset(-fadeLength); 128 129 mMoreActionsView = rootView.findViewById(R.id.details_overview_actions_more); 130 } 131 } 132 133 private final Presenter mDetailsPresenter; 134 private final ActionPresenterSelector mActionPresenterSelector; 135 private final ItemBridgeAdapter mActionBridgeAdapter; 136 private int mBackgroundColor = Color.TRANSPARENT; 137 private boolean mBackgroundColorSet; 138 private boolean mIsStyleLarge = true; 139 140 /** 141 * Constructor that uses the given {@link Presenter} to render the detailed 142 * description for the row. 143 */ 144 public DetailsOverviewRowPresenter(Presenter detailsPresenter) { 145 setHeaderPresenter(null); 146 setSelectEffectEnabled(false); 147 mDetailsPresenter = detailsPresenter; 148 mActionPresenterSelector = new ActionPresenterSelector(); 149 mActionBridgeAdapter = new ItemBridgeAdapter(); 150 } 151 152 /** 153 * Sets the listener for action click events. 154 */ 155 public void setOnActionClickedListener(OnActionClickedListener listener) { 156 mActionPresenterSelector.setOnActionClickedListener(listener); 157 } 158 159 /** 160 * Gets the listener for action click events. 161 */ 162 public OnActionClickedListener getOnActionClickedListener() { 163 return mActionPresenterSelector.getOnActionClickedListener(); 164 } 165 166 /** 167 * Sets the background color. If not set a default from the theme will be used. 168 */ 169 public void setBackgroundColor(int color) { 170 mBackgroundColor = color; 171 mBackgroundColorSet = true; 172 } 173 174 /** 175 * Returns the background color. If no background color was set, returns transparent. 176 */ 177 public int getBackgroundColor() { 178 return mBackgroundColor; 179 } 180 181 /** 182 * Sets the layout style to be large or small. 183 * The default is large. 184 */ 185 public void setStyleLarge(boolean large) { 186 mIsStyleLarge = large; 187 } 188 189 /** 190 * Returns true if the layout style is large. 191 */ 192 public boolean isStyleLarge() { 193 return mIsStyleLarge; 194 } 195 196 private int getDefaultBackgroundColor(Context context) { 197 TypedValue outValue = new TypedValue(); 198 context.getTheme().resolveAttribute(android.R.attr.colorBackground, outValue, true); 199 return context.getResources().getColor(outValue.resourceId); 200 } 201 202 @Override 203 protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) { 204 View v = LayoutInflater.from(parent.getContext()) 205 .inflate(R.layout.lb_details_overview, parent, false); 206 ViewHolder vh = new ViewHolder(v); 207 208 vh.mDetailsDescriptionViewHolder = 209 mDetailsPresenter.onCreateViewHolder(vh.mDetailsDescriptionFrame); 210 vh.mDetailsDescriptionFrame.addView(vh.mDetailsDescriptionViewHolder.view); 211 212 initDetailsOverview(v.findViewById(R.id.details_overview)); 213 214 return vh; 215 } 216 217 private void initDetailsOverview(View view) { 218 int resId = mIsStyleLarge ? R.dimen.lb_details_overview_height_large : 219 R.dimen.lb_details_overview_height_small; 220 221 ViewGroup.LayoutParams lp = view.getLayoutParams(); 222 lp.height = view.getResources().getDimensionPixelSize(resId); 223 view.setLayoutParams(lp); 224 225 view.setBackgroundColor(mBackgroundColorSet ? 226 mBackgroundColor : getDefaultBackgroundColor(view.getContext())); 227 228 } 229 230 @Override 231 protected void onBindRowViewHolder(RowPresenter.ViewHolder holder, Object item) { 232 super.onBindRowViewHolder(holder, item); 233 234 DetailsOverviewRow row = (DetailsOverviewRow) item; 235 ViewHolder vh = (ViewHolder) holder; 236 if (row.getImageDrawable() != null) { 237 vh.mImageView.setImageDrawable(row.getImageDrawable()); 238 } 239 if (vh.mDetailsDescriptionViewHolder == null) { 240 } 241 mDetailsPresenter.onBindViewHolder(vh.mDetailsDescriptionViewHolder, row); 242 243 mActionBridgeAdapter.clear(); 244 ArrayObjectAdapter aoa = new ArrayObjectAdapter(mActionPresenterSelector); 245 aoa.addAll(0, (Collection)row.getActions()); 246 vh.mScrollListener.bind(aoa); 247 248 mActionBridgeAdapter.setAdapter(aoa); 249 vh.mActionsRow.setAdapter(mActionBridgeAdapter); 250 } 251 252 @Override 253 protected void onUnbindRowViewHolder(RowPresenter.ViewHolder holder) { 254 super.onUnbindRowViewHolder(holder); 255 256 ViewHolder vh = (ViewHolder) holder; 257 if (vh.mDetailsDescriptionViewHolder != null) { 258 mDetailsPresenter.onUnbindViewHolder(vh.mDetailsDescriptionViewHolder); 259 } 260 261 vh.mActionsRow.setAdapter(null); 262 } 263} 264