AbstractDetailsDescriptionPresenter.java revision 7c004076d5289caa0af7b5fb04cf7a3374be56b1
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.graphics.Paint.FontMetricsInt; 18import android.support.v17.leanback.R; 19import android.text.TextUtils; 20import android.view.LayoutInflater; 21import android.view.View; 22import android.view.ViewGroup; 23import android.widget.TextView; 24 25/** 26 * An abstract {@link Presenter} for rendering a detailed description of an 27 * item. Typically this Presenter will be used in a DetailsOveriewRowPresenter. 28 * 29 * <p>Subclasses will override {@link #onBindDescription} to implement the data 30 * binding for this Presenter. 31 */ 32public abstract class AbstractDetailsDescriptionPresenter extends Presenter { 33 34 public static class ViewHolder extends Presenter.ViewHolder { 35 private final TextView mTitle; 36 private final TextView mSubtitle; 37 private final TextView mBody; 38 private final int mTitleMargin; 39 private final int mUnderTitleBaseline; 40 private final int mUnderSubtitleBaseline; 41 private final int mBodyLineSpacing; 42 private final int mSubtitleAscent; 43 private final int mBodyAscent; 44 45 public ViewHolder(View view) { 46 super(view); 47 mTitle = (TextView) view.findViewById(R.id.lb_details_description_title); 48 mSubtitle = (TextView) view.findViewById(R.id.lb_details_description_subtitle); 49 mBody = (TextView) view.findViewById(R.id.lb_details_description_body); 50 51 FontMetricsInt titleFontMetricsInt = getFontMetricsInt(mTitle); 52 final int titleAscent = view.getResources().getDimensionPixelSize( 53 R.dimen.lb_details_description_title_baseline); 54 // Ascent is negative 55 mTitleMargin = titleAscent + titleFontMetricsInt.ascent; 56 57 mUnderTitleBaseline = view.getResources().getDimensionPixelSize( 58 R.dimen.lb_details_description_under_title_baseline); 59 mUnderSubtitleBaseline = view.getResources().getDimensionPixelSize( 60 R.dimen.lb_details_description_under_subtitle_baseline); 61 62 FontMetricsInt subtitleFontMetricsInt = getFontMetricsInt(mSubtitle); 63 mSubtitleAscent = subtitleFontMetricsInt.ascent; 64 65 FontMetricsInt bodyFontMetricsInt = getFontMetricsInt(mBody); 66 mBodyAscent = bodyFontMetricsInt.ascent; 67 68 mBodyLineSpacing = view.getResources().getDimensionPixelSize( 69 R.dimen.lb_details_description_body_line_spacing); 70 } 71 72 public TextView getTitle() { 73 return mTitle; 74 } 75 76 public TextView getSubtitle() { 77 return mSubtitle; 78 } 79 80 public TextView getBody() { 81 return mBody; 82 } 83 84 private FontMetricsInt getFontMetricsInt(TextView textView) { 85 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); 86 paint.setTextSize(textView.getTextSize()); 87 paint.setTypeface(textView.getTypeface()); 88 return paint.getFontMetricsInt(); 89 } 90 } 91 92 @Override 93 public final ViewHolder onCreateViewHolder(ViewGroup parent) { 94 View v = LayoutInflater.from(parent.getContext()) 95 .inflate(R.layout.lb_details_description, parent, false); 96 return new ViewHolder(v); 97 } 98 99 @Override 100 public final void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) { 101 ViewHolder vh = (ViewHolder) viewHolder; 102 DetailsOverviewRow row = (DetailsOverviewRow) item; 103 onBindDescription(vh, row.getItem()); 104 105 boolean hasTitle = true; 106 if (TextUtils.isEmpty(vh.mTitle.getText())) { 107 vh.mTitle.setVisibility(View.GONE); 108 hasTitle = false; 109 } else { 110 vh.mTitle.setVisibility(View.VISIBLE); 111 } 112 setTopMargin(vh.mTitle, vh.mTitleMargin); 113 114 boolean hasSubtitle = true; 115 if (TextUtils.isEmpty(vh.mSubtitle.getText())) { 116 vh.mSubtitle.setVisibility(View.GONE); 117 hasSubtitle = false; 118 } else { 119 vh.mSubtitle.setVisibility(View.VISIBLE); 120 if (hasTitle) { 121 setTopMargin(vh.mSubtitle, vh.mUnderTitleBaseline + vh.mSubtitleAscent); 122 } else { 123 setTopMargin(vh.mSubtitle, 0); 124 } 125 } 126 127 if (TextUtils.isEmpty(vh.mBody.getText())) { 128 vh.mBody.setVisibility(View.GONE); 129 } else { 130 vh.mBody.setVisibility(View.VISIBLE); 131 vh.mBody.setLineSpacing(vh.mBodyLineSpacing - vh.mBody.getLineHeight() - 132 vh.mBody.getLineSpacingExtra(), vh.mBody.getLineSpacingMultiplier()); 133 134 if (hasSubtitle) { 135 setTopMargin(vh.mBody, vh.mUnderSubtitleBaseline + vh.mBodyAscent); 136 } else if (hasTitle) { 137 setTopMargin(vh.mBody, vh.mUnderTitleBaseline + vh.mBodyAscent); 138 } else { 139 setTopMargin(vh.mBody, 0); 140 } 141 } 142 } 143 144 /** 145 * Binds the data from the item referenced in the DetailsOverviewRow to the 146 * ViewHolder. 147 * 148 * @param vh The ViewHolder for this details description view. 149 * @param item The item from the DetailsOverviewRow being presented. 150 */ 151 protected abstract void onBindDescription(ViewHolder vh, Object item); 152 153 @Override 154 public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {} 155 156 private void setTopMargin(TextView textView, int topMargin) { 157 ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) textView.getLayoutParams(); 158 lp.topMargin = topMargin; 159 textView.setLayoutParams(lp); 160 } 161} 162