• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.internal.widget;
18 
19 import android.annotation.Nullable;
20 import android.content.Context;
21 import android.text.BoringLayout;
22 import android.text.Layout;
23 import android.text.StaticLayout;
24 import android.text.TextUtils;
25 import android.util.AttributeSet;
26 import android.view.RemotableViewMethod;
27 import android.widget.RemoteViews;
28 import android.widget.TextView;
29 
30 import com.android.internal.R;
31 
32 /**
33  * A TextView that can float around an image on the end.
34  *
35  * @hide
36  */
37 @RemoteViews.RemoteView
38 public class ImageFloatingTextView extends TextView {
39 
40     /** Number of lines from the top to indent */
41     private int mIndentLines;
42 
ImageFloatingTextView(Context context)43     public ImageFloatingTextView(Context context) {
44         this(context, null);
45     }
46 
ImageFloatingTextView(Context context, @Nullable AttributeSet attrs)47     public ImageFloatingTextView(Context context, @Nullable AttributeSet attrs) {
48         this(context, attrs, 0);
49     }
50 
ImageFloatingTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr)51     public ImageFloatingTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
52         this(context, attrs, defStyleAttr, 0);
53     }
54 
ImageFloatingTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)55     public ImageFloatingTextView(Context context, AttributeSet attrs, int defStyleAttr,
56             int defStyleRes) {
57         super(context, attrs, defStyleAttr, defStyleRes);
58     }
59 
60     @Override
makeSingleLayout(int wantWidth, BoringLayout.Metrics boring, int ellipsisWidth, Layout.Alignment alignment, boolean shouldEllipsize, TextUtils.TruncateAt effectiveEllipsize, boolean useSaved)61     protected Layout makeSingleLayout(int wantWidth, BoringLayout.Metrics boring, int ellipsisWidth,
62             Layout.Alignment alignment, boolean shouldEllipsize,
63             TextUtils.TruncateAt effectiveEllipsize, boolean useSaved) {
64         CharSequence text = getText() == null ? "" : getText();
65         StaticLayout.Builder builder = StaticLayout.Builder.obtain(text, 0, text.length(),
66                 getPaint(), wantWidth)
67                 .setAlignment(alignment)
68                 .setTextDirection(getTextDirectionHeuristic())
69                 .setLineSpacing(getLineSpacingExtra(), getLineSpacingMultiplier())
70                 .setIncludePad(getIncludeFontPadding())
71                 .setEllipsize(shouldEllipsize ? effectiveEllipsize : null)
72                 .setEllipsizedWidth(ellipsisWidth)
73                 .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
74                 .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
75         // we set the endmargin on the requested number of lines.
76         int endMargin = getContext().getResources().getDimensionPixelSize(
77                 R.dimen.notification_content_picture_margin);
78         int[] margins = null;
79         if (mIndentLines > 0) {
80             margins = new int[mIndentLines + 1];
81             for (int i = 0; i < mIndentLines; i++) {
82                 margins[i] = endMargin;
83             }
84         }
85         if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
86             builder.setIndents(margins, null);
87         } else {
88             builder.setIndents(null, margins);
89         }
90 
91         return builder.build();
92     }
93 
94     @RemotableViewMethod
setHasImage(boolean hasImage)95     public void setHasImage(boolean hasImage) {
96         setNumIndentLines(hasImage ? 2 : 0);
97     }
98 
99     /**
100      * @param lines the number of lines at the top that should be indented by indentEnd
101      * @return whether a change was made
102      */
setNumIndentLines(int lines)103     public boolean setNumIndentLines(int lines) {
104         if (mIndentLines != lines) {
105             mIndentLines = lines;
106             // Invalidate layout.
107             setHint(getHint());
108             return true;
109         }
110         return false;
111     }
112 }
113