AbstractDetailsDescriptionPresenter.java revision d2c235afaa4119599fd8bfc9bff65c5af9a8fdc1
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 mUnderTitleSpacing;
40        private final int mUnderSubtitleSpacing;
41
42        public ViewHolder(View view) {
43            super(view);
44            mTitle = (TextView) view.findViewById(R.id.lb_details_description_title);
45            mSubtitle = (TextView) view.findViewById(R.id.lb_details_description_subtitle);
46            mBody = (TextView) view.findViewById(R.id.lb_details_description_body);
47
48            FontMetricsInt titleFontMetricsInt = getFontMetricsInt(mTitle);
49            final int titleAscent = view.getResources().getDimensionPixelSize(
50                    R.dimen.lb_details_description_title_ascent);
51            // Ascent is negative
52            mTitleMargin = titleAscent + titleFontMetricsInt.ascent;
53
54            final int interTextSpacing = view.getResources().getDimensionPixelSize(
55                    R.dimen.lb_details_overview_description_intertext_spacing);
56            mUnderTitleSpacing = interTextSpacing - titleFontMetricsInt.descent;
57
58            FontMetricsInt subtitleFontMetricsInt = getFontMetricsInt(mSubtitle);
59            mUnderSubtitleSpacing = interTextSpacing - subtitleFontMetricsInt.descent;
60
61        }
62
63        public TextView getTitle() {
64            return mTitle;
65        }
66
67        public TextView getSubtitle() {
68            return mSubtitle;
69        }
70
71        public TextView getBody() {
72            return mBody;
73        }
74
75        private FontMetricsInt getFontMetricsInt(TextView textView) {
76            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
77            paint.setTextSize(textView.getTextSize());
78            paint.setTypeface(textView.getTypeface());
79            return paint.getFontMetricsInt();
80        }
81    }
82
83    @Override
84    public final ViewHolder onCreateViewHolder(ViewGroup parent) {
85        View v = LayoutInflater.from(parent.getContext())
86            .inflate(R.layout.lb_details_description, parent, false);
87        return new ViewHolder(v);
88    }
89
90    @Override
91    public final void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
92        ViewHolder vh = (ViewHolder) viewHolder;
93        DetailsOverviewRow row = (DetailsOverviewRow) item;
94        onBindDescription(vh, row.getItem());
95
96        boolean hasTitle = true;
97        if (TextUtils.isEmpty(vh.mTitle.getText())) {
98            vh.mTitle.setVisibility(View.GONE);
99            hasTitle = false;
100        } else {
101            vh.mTitle.setVisibility(View.VISIBLE);
102        }
103        setTopMargin(vh.mTitle, vh.mTitleMargin);
104
105        boolean hasSubtitle = true;
106        if (TextUtils.isEmpty(vh.mSubtitle.getText())) {
107            vh.mSubtitle.setVisibility(View.GONE);
108            hasSubtitle = false;
109        } else {
110            vh.mSubtitle.setVisibility(View.VISIBLE);
111            if (hasTitle) {
112                setTopMargin(vh.mSubtitle, vh.mUnderTitleSpacing);
113            } else {
114                setTopMargin(vh.mSubtitle, 0);
115            }
116        }
117
118        if (TextUtils.isEmpty(vh.mBody.getText())) {
119            vh.mBody.setVisibility(View.GONE);
120        } else {
121            vh.mBody.setVisibility(View.VISIBLE);
122            if (hasSubtitle) {
123                setTopMargin(vh.mBody, vh.mUnderSubtitleSpacing);
124            } else if (hasTitle) {
125                setTopMargin(vh.mBody, vh.mUnderTitleSpacing);
126            } else {
127                setTopMargin(vh.mBody, 0);
128            }
129        }
130    }
131
132    /**
133     * Binds the data from the item referenced in the DetailsOverviewRow to the
134     * ViewHolder.
135     *
136     * @param vh The ViewHolder for this details description view.
137     * @param item The item from the DetailsOverviewRow being presented.
138     */
139    protected abstract void onBindDescription(ViewHolder vh, Object item);
140
141    @Override
142    public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {}
143
144    private void setTopMargin(TextView textView, int topMargin) {
145        ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) textView.getLayoutParams();
146        lp.topMargin = topMargin;
147        textView.setLayoutParams(lp);
148    }
149}
150