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