ImageFloatingTextView.java revision 98199ae4c979ea1cac62eb9871649d6ec1dd159f
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.internal.widget;
18
19import android.annotation.Nullable;
20import android.content.Context;
21import android.text.BoringLayout;
22import android.text.Layout;
23import android.text.StaticLayout;
24import android.text.TextUtils;
25import android.util.AttributeSet;
26import android.view.RemotableViewMethod;
27import android.widget.RemoteViews;
28import android.widget.TextView;
29
30/**
31 * A TextView that can float around an image on the end.
32 *
33 * @hide
34 */
35@RemoteViews.RemoteView
36public class ImageFloatingTextView extends TextView {
37
38    private boolean mHasImage;
39
40    public ImageFloatingTextView(Context context) {
41        this(context, null);
42    }
43
44    public ImageFloatingTextView(Context context, @Nullable AttributeSet attrs) {
45        this(context, attrs, 0);
46    }
47
48    public ImageFloatingTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
49        this(context, attrs, defStyleAttr, 0);
50    }
51
52    public ImageFloatingTextView(Context context, AttributeSet attrs, int defStyleAttr,
53            int defStyleRes) {
54        super(context, attrs, defStyleAttr, defStyleRes);
55    }
56
57    @Override
58    protected Layout makeSingleLayout(int wantWidth, BoringLayout.Metrics boring, int ellipsisWidth,
59            Layout.Alignment alignment, boolean shouldEllipsize,
60            TextUtils.TruncateAt effectiveEllipsize, boolean useSaved) {
61        CharSequence text = getText() == null ? "" : getText();
62        StaticLayout.Builder builder = StaticLayout.Builder.obtain(text, 0, text.length(),
63                getPaint(), wantWidth)
64                .setAlignment(alignment)
65                .setTextDirection(getTextDirectionHeuristic())
66                .setLineSpacing(getLineSpacingExtra(), getLineSpacingMultiplier())
67                .setIncludePad(getIncludeFontPadding())
68                .setEllipsize(shouldEllipsize ? effectiveEllipsize : null)
69                .setEllipsizedWidth(ellipsisWidth)
70                .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
71                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
72        // we set the endmargin on the first 2 lines. this works just in our case but that's
73        // sufficient for now.
74        int endMargin = (int) (getResources().getDisplayMetrics().density * 52);
75        int[] margins = mHasImage ? new int[] {endMargin, endMargin, 0} : null;
76        if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
77            builder.setIndents(margins, null);
78        } else {
79            builder.setIndents(null, margins);
80        }
81
82        return builder.build();
83    }
84
85    @RemotableViewMethod
86    public void setHasImage(boolean hasImage) {
87        mHasImage = hasImage;
88        // The new layout will be automatically created when the text is
89        // set again by the notification.
90    }
91}
92