blob: 13ac9ff2ddaf2a03a847ffd18446d8cf0e5d3d7f [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 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 android.text.style;
18
Tor Norbye7b9c9122013-05-30 16:48:33 -070019import android.annotation.DrawableRes;
Florina Muntenescu139e1b52018-01-24 15:52:00 +000020import android.annotation.NonNull;
21import android.annotation.Nullable;
Mathew Inwood9cf99fd2018-08-14 15:31:03 +010022import android.annotation.UnsupportedAppUsage;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.content.Context;
24import android.graphics.Bitmap;
25import android.graphics.BitmapFactory;
26import android.graphics.drawable.BitmapDrawable;
27import android.graphics.drawable.Drawable;
28import android.net.Uri;
29import android.util.Log;
30
31import java.io.InputStream;
32
Florina Muntenescu139e1b52018-01-24 15:52:00 +000033/**
34 * Span that replaces the text it's attached to with a {@link Drawable} that can be aligned with
35 * the bottom or with the baseline of the surrounding text. The drawable can be constructed from
36 * varied sources:
37 * <ul>
38 * <li>{@link Bitmap} - see {@link #ImageSpan(Context, Bitmap)} and
39 * {@link #ImageSpan(Context, Bitmap, int)}
40 * </li>
41 * <li>{@link Drawable} - see {@link #ImageSpan(Drawable, int)}</li>
42 * <li>resource id - see {@link #ImageSpan(Context, int, int)}</li>
43 * <li>{@link Uri} - see {@link #ImageSpan(Context, Uri, int)}</li>
44 * </ul>
45 * The default value for the vertical alignment is {@link DynamicDrawableSpan#ALIGN_BOTTOM}
46 * <p>
47 * For example, an <code>ImagedSpan</code> can be used like this:
48 * <pre>
49 * SpannableString string = SpannableString("Bottom: span.\nBaseline: span.");
50 * // using the default alignment: ALIGN_BOTTOM
51 * string.setSpan(ImageSpan(this, R.mipmap.ic_launcher), 7, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
52 * string.setSpan(ImageSpan(this, R.mipmap.ic_launcher, DynamicDrawableSpan.ALIGN_BASELINE),
53 * 22, 23, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
54 * </pre>
55 * <img src="{@docRoot}reference/android/images/text/style/imagespan.png" />
56 * <figcaption>Text with <code>ImageSpan</code>s aligned bottom and baseline.</figcaption>
57 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058public class ImageSpan extends DynamicDrawableSpan {
Florina Muntenescu139e1b52018-01-24 15:52:00 +000059
60 @Nullable
Mathew Inwood9cf99fd2018-08-14 15:31:03 +010061 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062 private Drawable mDrawable;
Florina Muntenescu139e1b52018-01-24 15:52:00 +000063 @Nullable
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064 private Uri mContentUri;
Florina Muntenescu139e1b52018-01-24 15:52:00 +000065 @DrawableRes
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066 private int mResourceId;
Florina Muntenescu139e1b52018-01-24 15:52:00 +000067 @Nullable
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068 private Context mContext;
Florina Muntenescu139e1b52018-01-24 15:52:00 +000069 @Nullable
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070 private String mSource;
71
Dianne Hackborn0cd63762009-07-29 17:36:27 -070072 /**
73 * @deprecated Use {@link #ImageSpan(Context, Bitmap)} instead.
74 */
Dianne Hackborn4a51c202009-08-21 15:14:02 -070075 @Deprecated
Florina Muntenescu139e1b52018-01-24 15:52:00 +000076 public ImageSpan(@NonNull Bitmap b) {
Dianne Hackborn0cd63762009-07-29 17:36:27 -070077 this(null, b, ALIGN_BOTTOM);
78 }
79
80 /**
Elliot Waite54de7742017-01-11 15:30:35 -080081 * @deprecated Use {@link #ImageSpan(Context, Bitmap, int)} instead.
Dianne Hackborn0cd63762009-07-29 17:36:27 -070082 */
Dianne Hackborn4a51c202009-08-21 15:14:02 -070083 @Deprecated
Florina Muntenescu139e1b52018-01-24 15:52:00 +000084 public ImageSpan(@NonNull Bitmap b, int verticalAlignment) {
Dianne Hackborn0cd63762009-07-29 17:36:27 -070085 this(null, b, verticalAlignment);
86 }
87
Florina Muntenescu139e1b52018-01-24 15:52:00 +000088 /**
89 * Constructs an {@link ImageSpan} from a {@link Context} and a {@link Bitmap} with the default
90 * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}
91 *
92 * @param context context used to create a drawable from {@param bitmap} based on the display
93 * metrics of the resources
94 * @param bitmap bitmap to be rendered
95 */
96 public ImageSpan(@NonNull Context context, @NonNull Bitmap bitmap) {
97 this(context, bitmap, ALIGN_BOTTOM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 }
99
100 /**
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000101 * Constructs an {@link ImageSpan} from a {@link Context}, a {@link Bitmap} and a vertical
102 * alignment.
103 *
104 * @param context context used to create a drawable from {@param bitmap} based on
105 * the display metrics of the resources
106 * @param bitmap bitmap to be rendered
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000108 * {@link DynamicDrawableSpan#ALIGN_BASELINE}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 */
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000110 public ImageSpan(@NonNull Context context, @NonNull Bitmap bitmap, int verticalAlignment) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 super(verticalAlignment);
Dianne Hackborn0cd63762009-07-29 17:36:27 -0700112 mContext = context;
113 mDrawable = context != null
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000114 ? new BitmapDrawable(context.getResources(), bitmap)
115 : new BitmapDrawable(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 int width = mDrawable.getIntrinsicWidth();
117 int height = mDrawable.getIntrinsicHeight();
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000118 mDrawable.setBounds(0, 0, width > 0 ? width : 0, height > 0 ? height : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 }
120
121 /**
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000122 * Constructs an {@link ImageSpan} from a drawable with the default
123 * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}.
124 *
125 * @param drawable drawable to be rendered
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 */
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000127 public ImageSpan(@NonNull Drawable drawable) {
128 this(drawable, ALIGN_BOTTOM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 }
130
131 /**
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000132 * Constructs an {@link ImageSpan} from a drawable and a vertical alignment.
133 *
134 * @param drawable drawable to be rendered
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000136 * {@link DynamicDrawableSpan#ALIGN_BASELINE}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 */
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000138 public ImageSpan(@NonNull Drawable drawable, int verticalAlignment) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 super(verticalAlignment);
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000140 mDrawable = drawable;
141 }
142
143 /**
144 * Constructs an {@link ImageSpan} from a drawable and a source with the default
145 * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}
146 *
147 * @param drawable drawable to be rendered
148 * @param source drawable's Uri source
149 */
150 public ImageSpan(@NonNull Drawable drawable, @NonNull String source) {
151 this(drawable, source, ALIGN_BOTTOM);
152 }
153
154 /**
155 * Constructs an {@link ImageSpan} from a drawable, a source and a vertical alignment.
156 *
157 * @param drawable drawable to be rendered
158 * @param source drawable's uri source
159 * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
160 * {@link DynamicDrawableSpan#ALIGN_BASELINE}
161 */
162 public ImageSpan(@NonNull Drawable drawable, @NonNull String source, int verticalAlignment) {
163 super(verticalAlignment);
164 mDrawable = drawable;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 mSource = source;
166 }
167
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000168 /**
169 * Constructs an {@link ImageSpan} from a {@link Context} and a {@link Uri} with the default
170 * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}. The Uri source can be retrieved via
171 * {@link #getSource()}
172 *
173 * @param context context used to create a drawable from {@param bitmap} based on the display
174 * metrics of the resources
175 * @param uri {@link Uri} used to construct the drawable that will be rendered
176 */
177 public ImageSpan(@NonNull Context context, @NonNull Uri uri) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 this(context, uri, ALIGN_BOTTOM);
179 }
180
181 /**
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000182 * Constructs an {@link ImageSpan} from a {@link Context}, a {@link Uri} and a vertical
183 * alignment. The Uri source can be retrieved via {@link #getSource()}
184 *
185 * @param context context used to create a drawable from {@param bitmap} based on
186 * the display
187 * metrics of the resources
188 * @param uri {@link Uri} used to construct the drawable that will be rendered.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000190 * {@link DynamicDrawableSpan#ALIGN_BASELINE}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800191 */
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000192 public ImageSpan(@NonNull Context context, @NonNull Uri uri, int verticalAlignment) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 super(verticalAlignment);
194 mContext = context;
195 mContentUri = uri;
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700196 mSource = uri.toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 }
198
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000199 /**
200 * Constructs an {@link ImageSpan} from a {@link Context} and a resource id with the default
201 * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}
202 *
203 * @param context context used to retrieve the drawable from resources
204 * @param resourceId drawable resource id based on which the drawable is retrieved
205 */
206 public ImageSpan(@NonNull Context context, @DrawableRes int resourceId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 this(context, resourceId, ALIGN_BOTTOM);
208 }
209
210 /**
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000211 * Constructs an {@link ImageSpan} from a {@link Context}, a resource id and a vertical
212 * alignment.
213 *
214 * @param context context used to retrieve the drawable from resources
215 * @param resourceId drawable resource id based on which the drawable is retrieved.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000217 * {@link DynamicDrawableSpan#ALIGN_BASELINE}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 */
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000219 public ImageSpan(@NonNull Context context, @DrawableRes int resourceId,
220 int verticalAlignment) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 super(verticalAlignment);
222 mContext = context;
223 mResourceId = resourceId;
224 }
225
226 @Override
227 public Drawable getDrawable() {
228 Drawable drawable = null;
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230 if (mDrawable != null) {
231 drawable = mDrawable;
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000232 } else if (mContentUri != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233 Bitmap bitmap = null;
234 try {
235 InputStream is = mContext.getContentResolver().openInputStream(
236 mContentUri);
237 bitmap = BitmapFactory.decodeStream(is);
Dianne Hackborn11ea3342009-07-22 21:48:55 -0700238 drawable = new BitmapDrawable(mContext.getResources(), bitmap);
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700239 drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
240 drawable.getIntrinsicHeight());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 is.close();
242 } catch (Exception e) {
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000243 Log.e("ImageSpan", "Failed to loaded content " + mContentUri, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 }
245 } else {
246 try {
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800247 drawable = mContext.getDrawable(mResourceId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
249 drawable.getIntrinsicHeight());
250 } catch (Exception e) {
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000251 Log.e("ImageSpan", "Unable to find resource: " + mResourceId);
252 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 }
254
255 return drawable;
256 }
257
258 /**
259 * Returns the source string that was saved during construction.
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000260 *
261 * @return the source string that was saved during construction
Andrew Solovay6eaf48ea2018-12-12 15:38:06 -0800262 * @see #ImageSpan(Drawable, String)
263 * @see #ImageSpan(Context, Uri)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 */
Florina Muntenescu139e1b52018-01-24 15:52:00 +0000265 @Nullable
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 public String getSource() {
267 return mSource;
268 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269}