147520b68e50572a9775a662410c5aff8300c8784Craig Stout/* 247520b68e50572a9775a662410c5aff8300c8784Craig Stout * Copyright (C) 2014 The Android Open Source Project 347520b68e50572a9775a662410c5aff8300c8784Craig Stout * 447520b68e50572a9775a662410c5aff8300c8784Craig Stout * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 547520b68e50572a9775a662410c5aff8300c8784Craig Stout * in compliance with the License. You may obtain a copy of the License at 647520b68e50572a9775a662410c5aff8300c8784Craig Stout * 747520b68e50572a9775a662410c5aff8300c8784Craig Stout * http://www.apache.org/licenses/LICENSE-2.0 847520b68e50572a9775a662410c5aff8300c8784Craig Stout * 947520b68e50572a9775a662410c5aff8300c8784Craig Stout * Unless required by applicable law or agreed to in writing, software distributed under the License 1047520b68e50572a9775a662410c5aff8300c8784Craig Stout * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 1147520b68e50572a9775a662410c5aff8300c8784Craig Stout * or implied. See the License for the specific language governing permissions and limitations under 1247520b68e50572a9775a662410c5aff8300c8784Craig Stout * the License. 1347520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 1447520b68e50572a9775a662410c5aff8300c8784Craig Stoutpackage android.support.v17.leanback.widget; 1547520b68e50572a9775a662410c5aff8300c8784Craig Stout 164cd4cce277571385f4d1a56d5348578c38368cbeCraig Stoutimport android.graphics.Paint; 174cf79b1c4d38a190317961891f9fd052836710fdCraig Stoutimport android.support.v17.leanback.R; 18268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stoutimport android.view.LayoutInflater; 1947520b68e50572a9775a662410c5aff8300c8784Craig Stoutimport android.view.View; 2047520b68e50572a9775a662410c5aff8300c8784Craig Stoutimport android.view.ViewGroup; 214cd4cce277571385f4d1a56d5348578c38368cbeCraig Stoutimport android.widget.TextView; 2247520b68e50572a9775a662410c5aff8300c8784Craig Stout 2347520b68e50572a9775a662410c5aff8300c8784Craig Stout/** 24a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * RowHeaderPresenter provides a default presentation for {@link HeaderItem} using a 25a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * {@link RowHeaderView}. If a subclass creates its own view, the subclass must also override 26cb13a318e577e14461eb008071dddf762847de42Dake Gu * {@link #onSelectLevelChanged(ViewHolder)}. 2747520b68e50572a9775a662410c5aff8300c8784Craig Stout */ 2847520b68e50572a9775a662410c5aff8300c8784Craig Stoutpublic class RowHeaderPresenter extends Presenter { 2947520b68e50572a9775a662410c5aff8300c8784Craig Stout 30268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout private final int mLayoutResourceId; 314cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout private final Paint mFontMeasurePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 32ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout private boolean mNullItemVisibilityGone; 338ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu private final boolean mAnimateSelect; 34268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout 35268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout public RowHeaderPresenter() { 36268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout this(R.layout.lb_row_header); 37268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout } 38268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout 39268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout /** 40268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout * @hide 41268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout */ 42268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout public RowHeaderPresenter(int layoutResourceId) { 438ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu this(layoutResourceId, true); 448ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 458ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu 468ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu /** 478ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu * @hide 488ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu */ 498ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu public RowHeaderPresenter(int layoutResourceId, boolean animateSelect) { 50268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout mLayoutResourceId = layoutResourceId; 518ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu mAnimateSelect = animateSelect; 52268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout } 53268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout 54ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout /** 55ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout * Optionally sets the view visibility to {@link View#GONE} when bound to null. 56ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout */ 57ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout public void setNullItemVisibilityGone(boolean nullItemVisibilityGone) { 58ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout mNullItemVisibilityGone = nullItemVisibilityGone; 59ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout } 60ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout 61ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout /** 62ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout * Returns true if the view visibility is set to {@link View#GONE} when bound to null. 63ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout */ 64ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout public boolean isNullItemVisibilityGone() { 65ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout return mNullItemVisibilityGone; 66ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout } 67ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout 68a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout /** 69a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * A ViewHolder for the RowHeaderPresenter. 70a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout */ 7147520b68e50572a9775a662410c5aff8300c8784Craig Stout public static class ViewHolder extends Presenter.ViewHolder { 72cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu float mSelectLevel; 73cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu int mOriginalTextColor; 74268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout float mUnselectAlpha; 75268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout 7647520b68e50572a9775a662410c5aff8300c8784Craig Stout public ViewHolder(View view) { 7747520b68e50572a9775a662410c5aff8300c8784Craig Stout super(view); 7847520b68e50572a9775a662410c5aff8300c8784Craig Stout } 79cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu public final float getSelectLevel() { 80cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu return mSelectLevel; 81cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 8247520b68e50572a9775a662410c5aff8300c8784Craig Stout } 8347520b68e50572a9775a662410c5aff8300c8784Craig Stout 8447520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 8547520b68e50572a9775a662410c5aff8300c8784Craig Stout public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) { 86268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout RowHeaderView headerView = (RowHeaderView) LayoutInflater.from(parent.getContext()) 87268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout .inflate(mLayoutResourceId, parent, false); 88268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout 89cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu ViewHolder viewHolder = new ViewHolder(headerView); 90cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu viewHolder.mOriginalTextColor = headerView.getCurrentTextColor(); 91268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout viewHolder.mUnselectAlpha = parent.getResources().getFraction( 92268de3d2ea3de1be0725a80bbc79dd7b8b18617eCraig Stout R.fraction.lb_browse_header_unselect_alpha, 1, 1); 938ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (mAnimateSelect) { 948ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu setSelectLevel(viewHolder, 0); 958ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 96cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu return viewHolder; 9747520b68e50572a9775a662410c5aff8300c8784Craig Stout } 9847520b68e50572a9775a662410c5aff8300c8784Craig Stout 9947520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 10047520b68e50572a9775a662410c5aff8300c8784Craig Stout public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) { 101ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout HeaderItem headerItem = item == null ? null : ((Row) item).getHeaderItem(); 102ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout if (headerItem == null) { 103ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout ((RowHeaderView) viewHolder.view).setText(null); 104ac30644710e427c77b9d1f20ae385590bdac6c60Dake Gu viewHolder.view.setContentDescription(null); 105ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout if (mNullItemVisibilityGone) { 106ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout viewHolder.view.setVisibility(View.GONE); 10747520b68e50572a9775a662410c5aff8300c8784Craig Stout } 108ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout } else { 109ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout viewHolder.view.setVisibility(View.VISIBLE); 110ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout ((RowHeaderView) viewHolder.view).setText(headerItem.getName()); 111ac30644710e427c77b9d1f20ae385590bdac6c60Dake Gu viewHolder.view.setContentDescription(headerItem.getContentDescription()); 11247520b68e50572a9775a662410c5aff8300c8784Craig Stout } 11347520b68e50572a9775a662410c5aff8300c8784Craig Stout } 11447520b68e50572a9775a662410c5aff8300c8784Craig Stout 11547520b68e50572a9775a662410c5aff8300c8784Craig Stout @Override 11647520b68e50572a9775a662410c5aff8300c8784Craig Stout public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) { 117ad9af35ec6a808136478daf7bd57d564ac517e0eCraig Stout ((RowHeaderView) viewHolder.view).setText(null); 1188ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (mAnimateSelect) { 1198ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu setSelectLevel((ViewHolder) viewHolder, 0); 1208ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 12147520b68e50572a9775a662410c5aff8300c8784Craig Stout } 122cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu 123a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout /** 124a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Sets the select level. 125a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout */ 126cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu public final void setSelectLevel(ViewHolder holder, float selectLevel) { 127cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu holder.mSelectLevel = selectLevel; 128cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu onSelectLevelChanged(holder); 129cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 130cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu 131a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout /** 132a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Called when the select level changes. The default implementation sets the alpha on the view. 133a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout */ 134cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu protected void onSelectLevelChanged(ViewHolder holder) { 1358ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu if (mAnimateSelect) { 1368ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu holder.view.setAlpha(holder.mUnselectAlpha + holder.mSelectLevel * 1378ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu (1f - holder.mUnselectAlpha)); 1388ff4c54cdaf5e8164fba7eac999c1ceafc462fc8Dake Gu } 139cf94c5fa8ae8edb7e26a623133207415ceeed187Dake Gu } 1404cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout 1414cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout /** 1424cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout * Returns the space (distance in pixels) below the baseline of the 1434cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout * text view, if one exists; otherwise, returns 0. 1444cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout */ 1454cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout public int getSpaceUnderBaseline(ViewHolder holder) { 1464cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout int space = holder.view.getPaddingBottom(); 1474cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout if (holder.view instanceof TextView) { 1484cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout space += (int) getFontDescent((TextView) holder.view, mFontMeasurePaint); 1494cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 1504cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout return space; 1514cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 1524cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout 1534cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout protected static float getFontDescent(TextView textView, Paint fontMeasurePaint) { 1544cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout if (fontMeasurePaint.getTextSize() != textView.getTextSize()) { 1554cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout fontMeasurePaint.setTextSize(textView.getTextSize()); 1564cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 1574cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout if (fontMeasurePaint.getTypeface() != textView.getTypeface()) { 1584cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout fontMeasurePaint.setTypeface(textView.getTypeface()); 1594cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 1604cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout return fontMeasurePaint.descent(); 1614cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout } 1624cd4cce277571385f4d1a56d5348578c38368cbeCraig Stout} 163