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