blob: a5d2bf3b68d3cf25361a4d5a58dd82bf883e8f5f [file] [log] [blame]
Selim Cinek4fb12d32015-11-19 18:10:48 -08001/*
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
Selim Cinek37878682016-05-02 13:40:58 -070030import com.android.internal.R;
31
Selim Cinek4fb12d32015-11-19 18:10:48 -080032/**
33 * A TextView that can float around an image on the end.
34 *
35 * @hide
36 */
37@RemoteViews.RemoteView
38public class ImageFloatingTextView extends TextView {
39
Adrian Roosc1a80b02016-04-05 14:54:55 -070040 /** Number of lines from the top to indent */
41 private int mIndentLines;
Selim Cinek4fb12d32015-11-19 18:10:48 -080042
dongwan0605.kimdd8611f2016-09-16 16:26:57 +090043 /** Resolved layout direction */
44 private int mResolvedDirection = LAYOUT_DIRECTION_UNDEFINED;
45
Selim Cinek4fb12d32015-11-19 18:10:48 -080046 public ImageFloatingTextView(Context context) {
47 this(context, null);
48 }
49
50 public ImageFloatingTextView(Context context, @Nullable AttributeSet attrs) {
51 this(context, attrs, 0);
52 }
53
54 public ImageFloatingTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
55 this(context, attrs, defStyleAttr, 0);
56 }
57
58 public ImageFloatingTextView(Context context, AttributeSet attrs, int defStyleAttr,
59 int defStyleRes) {
60 super(context, attrs, defStyleAttr, defStyleRes);
61 }
62
63 @Override
64 protected Layout makeSingleLayout(int wantWidth, BoringLayout.Metrics boring, int ellipsisWidth,
65 Layout.Alignment alignment, boolean shouldEllipsize,
66 TextUtils.TruncateAt effectiveEllipsize, boolean useSaved) {
67 CharSequence text = getText() == null ? "" : getText();
68 StaticLayout.Builder builder = StaticLayout.Builder.obtain(text, 0, text.length(),
69 getPaint(), wantWidth)
70 .setAlignment(alignment)
71 .setTextDirection(getTextDirectionHeuristic())
72 .setLineSpacing(getLineSpacingExtra(), getLineSpacingMultiplier())
73 .setIncludePad(getIncludeFontPadding())
Selim Cinek4fb12d32015-11-19 18:10:48 -080074 .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
Adrian Roos62be4392016-12-05 13:59:52 -080075 .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL)
76 .setMaxLines(getMaxLines() >= 0 ? getMaxLines() : Integer.MAX_VALUE);
77 if (shouldEllipsize) {
78 builder.setEllipsize(effectiveEllipsize)
79 .setEllipsizedWidth(ellipsisWidth);
80 }
81
Adrian Roosc1a80b02016-04-05 14:54:55 -070082 // we set the endmargin on the requested number of lines.
83 int endMargin = getContext().getResources().getDimensionPixelSize(
84 R.dimen.notification_content_picture_margin);
85 int[] margins = null;
86 if (mIndentLines > 0) {
87 margins = new int[mIndentLines + 1];
88 for (int i = 0; i < mIndentLines; i++) {
89 margins[i] = endMargin;
90 }
91 }
dongwan0605.kimdd8611f2016-09-16 16:26:57 +090092 if (mResolvedDirection == LAYOUT_DIRECTION_RTL) {
Selim Cinek4fb12d32015-11-19 18:10:48 -080093 builder.setIndents(margins, null);
94 } else {
95 builder.setIndents(null, margins);
96 }
97
98 return builder.build();
99 }
100
dongwan0605.kimdd8611f2016-09-16 16:26:57 +0900101 @Override
102 public void onRtlPropertiesChanged(int layoutDirection) {
103 super.onRtlPropertiesChanged(layoutDirection);
104
105 if (layoutDirection != mResolvedDirection && isLayoutDirectionResolved()) {
106 mResolvedDirection = layoutDirection;
107 if (mIndentLines > 0) {
108 // Invalidate layout.
109 setHint(getHint());
110 }
111 }
112 }
113
Selim Cinek4fb12d32015-11-19 18:10:48 -0800114 @RemotableViewMethod
115 public void setHasImage(boolean hasImage) {
Selim Cinek37878682016-05-02 13:40:58 -0700116 setNumIndentLines(hasImage ? 2 : 0);
Selim Cinek4fb12d32015-11-19 18:10:48 -0800117 }
Adrian Roosc1a80b02016-04-05 14:54:55 -0700118
119 /**
120 * @param lines the number of lines at the top that should be indented by indentEnd
121 * @return whether a change was made
122 */
123 public boolean setNumIndentLines(int lines) {
124 if (mIndentLines != lines) {
125 mIndentLines = lines;
126 // Invalidate layout.
127 setHint(getHint());
128 return true;
129 }
130 return false;
131 }
Selim Cinek4fb12d32015-11-19 18:10:48 -0800132}