RowHeaderPresenter.java revision c39d9c75590eca86a5e7e32a8824ba04a0d42e9b
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.graphics.Paint; 17import android.support.annotation.RestrictTo; 18import android.support.v17.leanback.R; 19import android.view.LayoutInflater; 20import android.view.View; 21import android.view.ViewGroup; 22import android.widget.TextView; 23 24import static android.support.annotation.RestrictTo.Scope.GROUP_ID; 25 26/** 27 * RowHeaderPresenter provides a default presentation for {@link HeaderItem} using a 28 * {@link RowHeaderView}. If a subclass creates its own view, the subclass must also override 29 * {@link #onSelectLevelChanged(ViewHolder)}. 30 */ 31public class RowHeaderPresenter extends Presenter { 32 33 private final int mLayoutResourceId; 34 private final Paint mFontMeasurePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 35 private boolean mNullItemVisibilityGone; 36 private final boolean mAnimateSelect; 37 38 public RowHeaderPresenter() { 39 this(R.layout.lb_row_header); 40 } 41 42 /** 43 * @hide 44 */ 45 @RestrictTo(GROUP_ID) 46 public RowHeaderPresenter(int layoutResourceId) { 47 this(layoutResourceId, true); 48 } 49 50 /** 51 * @hide 52 */ 53 @RestrictTo(GROUP_ID) 54 public RowHeaderPresenter(int layoutResourceId, boolean animateSelect) { 55 mLayoutResourceId = layoutResourceId; 56 mAnimateSelect = animateSelect; 57 } 58 59 /** 60 * Optionally sets the view visibility to {@link View#GONE} when bound to null. 61 */ 62 public void setNullItemVisibilityGone(boolean nullItemVisibilityGone) { 63 mNullItemVisibilityGone = nullItemVisibilityGone; 64 } 65 66 /** 67 * Returns true if the view visibility is set to {@link View#GONE} when bound to null. 68 */ 69 public boolean isNullItemVisibilityGone() { 70 return mNullItemVisibilityGone; 71 } 72 73 /** 74 * A ViewHolder for the RowHeaderPresenter. 75 */ 76 public static class ViewHolder extends Presenter.ViewHolder { 77 float mSelectLevel; 78 int mOriginalTextColor; 79 float mUnselectAlpha; 80 81 public ViewHolder(View view) { 82 super(view); 83 } 84 public final float getSelectLevel() { 85 return mSelectLevel; 86 } 87 } 88 89 @Override 90 public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) { 91 RowHeaderView headerView = (RowHeaderView) LayoutInflater.from(parent.getContext()) 92 .inflate(mLayoutResourceId, parent, false); 93 94 ViewHolder viewHolder = new ViewHolder(headerView); 95 viewHolder.mOriginalTextColor = headerView.getCurrentTextColor(); 96 viewHolder.mUnselectAlpha = parent.getResources().getFraction( 97 R.fraction.lb_browse_header_unselect_alpha, 1, 1); 98 if (mAnimateSelect) { 99 setSelectLevel(viewHolder, 0); 100 } 101 return viewHolder; 102 } 103 104 @Override 105 public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) { 106 HeaderItem headerItem = item == null ? null : ((Row) item).getHeaderItem(); 107 if (headerItem == null) { 108 ((RowHeaderView) viewHolder.view).setText(null); 109 viewHolder.view.setContentDescription(null); 110 if (mNullItemVisibilityGone) { 111 viewHolder.view.setVisibility(View.GONE); 112 } 113 } else { 114 viewHolder.view.setVisibility(View.VISIBLE); 115 ((RowHeaderView) viewHolder.view).setText(headerItem.getName()); 116 viewHolder.view.setContentDescription(headerItem.getContentDescription()); 117 } 118 } 119 120 @Override 121 public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) { 122 ((RowHeaderView) viewHolder.view).setText(null); 123 if (mAnimateSelect) { 124 setSelectLevel((ViewHolder) viewHolder, 0); 125 } 126 } 127 128 /** 129 * Sets the select level. 130 */ 131 public final void setSelectLevel(ViewHolder holder, float selectLevel) { 132 holder.mSelectLevel = selectLevel; 133 onSelectLevelChanged(holder); 134 } 135 136 /** 137 * Called when the select level changes. The default implementation sets the alpha on the view. 138 */ 139 protected void onSelectLevelChanged(ViewHolder holder) { 140 if (mAnimateSelect) { 141 holder.view.setAlpha(holder.mUnselectAlpha + holder.mSelectLevel * 142 (1f - holder.mUnselectAlpha)); 143 } 144 } 145 146 /** 147 * Returns the space (distance in pixels) below the baseline of the 148 * text view, if one exists; otherwise, returns 0. 149 */ 150 public int getSpaceUnderBaseline(ViewHolder holder) { 151 int space = holder.view.getPaddingBottom(); 152 if (holder.view instanceof TextView) { 153 space += (int) getFontDescent((TextView) holder.view, mFontMeasurePaint); 154 } 155 return space; 156 } 157 158 protected static float getFontDescent(TextView textView, Paint fontMeasurePaint) { 159 if (fontMeasurePaint.getTextSize() != textView.getTextSize()) { 160 fontMeasurePaint.setTextSize(textView.getTextSize()); 161 } 162 if (fontMeasurePaint.getTypeface() != textView.getTypeface()) { 163 fontMeasurePaint.setTypeface(textView.getTypeface()); 164 } 165 return fontMeasurePaint.descent(); 166 } 167} 168