ImageFloatingTextView.java revision 4fb12d3f8ebf20f2d6db519f7f91cfa625edf566
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                .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
69                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
70        // we set the endmargin on the first 2 lines. this works just in our case but that's
71        // sufficient for now.
72        int endMargin = (int) (getResources().getDisplayMetrics().density * 52);
73        int[] margins = mHasImage ? new int[] {endMargin, endMargin, 0} : null;
74        if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
75            builder.setIndents(margins, null);
76        } else {
77            builder.setIndents(null, margins);
78        }
79
80        return builder.build();
81    }
82
83    @RemotableViewMethod
84    public void setHasImage(boolean hasImage) {
85        mHasImage = hasImage;
86        // The new layout will be automatically created when the text is
87        // set again by the notification.
88    }
89}
90