Updating more spans
Test: N/A
Bug: 72092996
Change-Id: Iecd3595a03cde2a1d58e4be00b7cf9b6783d4e2a
diff --git a/core/java/android/text/style/DrawableMarginSpan.java b/core/java/android/text/style/DrawableMarginSpan.java
index 3524179..cd199b3 100644
--- a/core/java/android/text/style/DrawableMarginSpan.java
+++ b/core/java/android/text/style/DrawableMarginSpan.java
@@ -16,60 +16,100 @@
package android.text.style;
+import android.annotation.NonNull;
+import android.annotation.Px;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.Spanned;
-public class DrawableMarginSpan
-implements LeadingMarginSpan, LineHeightSpan
-{
- public DrawableMarginSpan(Drawable b) {
- mDrawable = b;
+/**
+ * A span which adds a drawable and a padding to the paragraph it's attached to.
+ * <p>
+ * If the height of the drawable is bigger than the height of the line it's attached to then the
+ * line height is increased to fit the drawable. <code>DrawableMarginSpan</code> allows setting a
+ * padding between the drawable and the text. The default value is 0. The span must be set from the
+ * beginning of the text, otherwise either the span won't be rendered or it will be rendered
+ * incorrectly.
+ * <p>
+ * For example, a drawable and a padding of 20px can be added like this:
+ * <pre>{@code SpannableString string = new SpannableString("Text with a drawable.");
+ * string.setSpan(new DrawableMarginSpan(drawable, 20), 0, string.length(),
+ * Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre>
+ * <img src="{@docRoot}reference/android/images/text/style/drawablemarginspan.png" />
+ * <figcaption>Text with a drawable and a padding.</figcaption>
+ * <p>
+ *
+ * @see IconMarginSpan for working with a {@link android.graphics.Bitmap} instead of
+ * a {@link Drawable}.
+ */
+public class DrawableMarginSpan implements LeadingMarginSpan, LineHeightSpan {
+ private static final int STANDARD_PAD_WIDTH = 0;
+
+ @NonNull
+ private final Drawable mDrawable;
+ @Px
+ private final int mPad;
+
+ /**
+ * Creates a {@link DrawableMarginSpan} from a {@link Drawable}. The pad width will be 0.
+ *
+ * @param drawable the drawable to be added
+ */
+ public DrawableMarginSpan(@NonNull Drawable drawable) {
+ this(drawable, STANDARD_PAD_WIDTH);
}
- public DrawableMarginSpan(Drawable b, int pad) {
- mDrawable = b;
+ /**
+ * Creates a {@link DrawableMarginSpan} from a {@link Drawable} and a padding, in pixels.
+ *
+ * @param drawable the drawable to be added
+ * @param pad the distance between the drawable and the text
+ */
+ public DrawableMarginSpan(@NonNull Drawable drawable, int pad) {
+ mDrawable = drawable;
mPad = pad;
}
+ @Override
public int getLeadingMargin(boolean first) {
return mDrawable.getIntrinsicWidth() + mPad;
}
- public void drawLeadingMargin(Canvas c, Paint p, int x, int dir,
- int top, int baseline, int bottom,
- CharSequence text, int start, int end,
- boolean first, Layout layout) {
+ @Override
+ public void drawLeadingMargin(@NonNull Canvas c, @NonNull Paint p, int x, int dir,
+ int top, int baseline, int bottom,
+ @NonNull CharSequence text, int start, int end,
+ boolean first, @NonNull Layout layout) {
int st = ((Spanned) text).getSpanStart(this);
- int ix = (int)x;
- int itop = (int)layout.getLineTop(layout.getLineForOffset(st));
+ int ix = (int) x;
+ int itop = (int) layout.getLineTop(layout.getLineForOffset(st));
int dw = mDrawable.getIntrinsicWidth();
int dh = mDrawable.getIntrinsicHeight();
// XXX What to do about Paint?
- mDrawable.setBounds(ix, itop, ix+dw, itop+dh);
+ mDrawable.setBounds(ix, itop, ix + dw, itop + dh);
mDrawable.draw(c);
}
- public void chooseHeight(CharSequence text, int start, int end,
- int istartv, int v,
- Paint.FontMetricsInt fm) {
+ @Override
+ public void chooseHeight(@NonNull CharSequence text, int start, int end,
+ int istartv, int v,
+ @NonNull Paint.FontMetricsInt fm) {
if (end == ((Spanned) text).getSpanEnd(this)) {
int ht = mDrawable.getIntrinsicHeight();
int need = ht - (v + fm.descent - fm.ascent - istartv);
- if (need > 0)
+ if (need > 0) {
fm.descent += need;
+ }
need = ht - (v + fm.bottom - fm.top - istartv);
- if (need > 0)
+ if (need > 0) {
fm.bottom += need;
+ }
}
}
-
- private Drawable mDrawable;
- private int mPad;
}
diff --git a/core/java/android/text/style/DynamicDrawableSpan.java b/core/java/android/text/style/DynamicDrawableSpan.java
index 5b8a6dd..1b16f33 100644
--- a/core/java/android/text/style/DynamicDrawableSpan.java
+++ b/core/java/android/text/style/DynamicDrawableSpan.java
@@ -16,6 +16,9 @@
package android.text.style;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
@@ -24,32 +27,71 @@
import java.lang.ref.WeakReference;
/**
+ * Span that replaces the text it's attached to with a {@link Drawable} that can be aligned with
+ * the bottom or with the baseline of the surrounding text.
+ * <p>
+ * For an implementation that constructs the drawable from various sources (<code>Bitmap</code>,
+ * <code>Drawable</code>, resource id or <code>Uri</code>) use {@link ImageSpan}.
+ * <p>
+ * A simple implementation of <code>DynamicDrawableSpan</code> that uses drawables from resources
+ * looks like this:
+ * <pre>
+ * class MyDynamicDrawableSpan extends DynamicDrawableSpan {
*
+ * private final Context mContext;
+ * private final int mResourceId;
+ *
+ * public MyDynamicDrawableSpan(Context context, @DrawableRes int resourceId) {
+ * mContext = context;
+ * mResourceId = resourceId;
+ * }
+ *
+ * {@literal @}Override
+ * public Drawable getDrawable() {
+ * Drawable drawable = mContext.getDrawable(mResourceId);
+ * drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
+ * return drawable;
+ * }
+ * }</pre>
+ * The class can be used like this:
+ * <pre>
+ * SpannableString string = new SpannableString("Text with a drawable span");
+ * string.setSpan(new MyDynamicDrawableSpan(context, R.mipmap.ic_launcher), 12, 20, Spanned
+ * .SPAN_EXCLUSIVE_EXCLUSIVE);</pre>
+ * <img src="{@docRoot}reference/android/images/text/style/dynamicdrawablespan.png" />
+ * <figcaption>Replacing text with a drawable.</figcaption>
*/
public abstract class DynamicDrawableSpan extends ReplacementSpan {
- private static final String TAG = "DynamicDrawableSpan";
-
+
/**
* A constant indicating that the bottom of this span should be aligned
* with the bottom of the surrounding text, i.e., at the same level as the
* lowest descender in the text.
*/
public static final int ALIGN_BOTTOM = 0;
-
+
/**
* A constant indicating that the bottom of this span should be aligned
* with the baseline of the surrounding text.
*/
public static final int ALIGN_BASELINE = 1;
-
+
protected final int mVerticalAlignment;
-
+
+ private WeakReference<Drawable> mDrawableRef;
+
+ /**
+ * Creates a {@link DynamicDrawableSpan}. The default vertical alignment is
+ * {@link #ALIGN_BOTTOM}
+ */
public DynamicDrawableSpan() {
mVerticalAlignment = ALIGN_BOTTOM;
}
/**
- * @param verticalAlignment one of {@link #ALIGN_BOTTOM} or {@link #ALIGN_BASELINE}.
+ * Creates a {@link DynamicDrawableSpan} based on a vertical alignment.\
+ *
+ * @param verticalAlignment one of {@link #ALIGN_BOTTOM} or {@link #ALIGN_BASELINE}
*/
protected DynamicDrawableSpan(int verticalAlignment) {
mVerticalAlignment = verticalAlignment;
@@ -64,22 +106,22 @@
}
/**
- * Your subclass must implement this method to provide the bitmap
+ * Your subclass must implement this method to provide the bitmap
* to be drawn. The dimensions of the bitmap must be the same
* from each call to the next.
*/
public abstract Drawable getDrawable();
@Override
- public int getSize(Paint paint, CharSequence text,
- int start, int end,
- Paint.FontMetricsInt fm) {
+ public int getSize(@NonNull Paint paint, CharSequence text,
+ @IntRange(from = 0) int start, @IntRange(from = 0) int end,
+ @Nullable Paint.FontMetricsInt fm) {
Drawable d = getCachedDrawable();
Rect rect = d.getBounds();
if (fm != null) {
- fm.ascent = -rect.bottom;
- fm.descent = 0;
+ fm.ascent = -rect.bottom;
+ fm.descent = 0;
fm.top = fm.ascent;
fm.bottom = 0;
@@ -89,12 +131,12 @@
}
@Override
- public void draw(Canvas canvas, CharSequence text,
- int start, int end, float x,
- int top, int y, int bottom, Paint paint) {
+ public void draw(@NonNull Canvas canvas, CharSequence text,
+ @IntRange(from = 0) int start, @IntRange(from = 0) int end, float x,
+ int top, int y, int bottom, @NonNull Paint paint) {
Drawable b = getCachedDrawable();
canvas.save();
-
+
int transY = bottom - b.getBounds().bottom;
if (mVerticalAlignment == ALIGN_BASELINE) {
transY -= paint.getFontMetricsInt().descent;
@@ -109,8 +151,9 @@
WeakReference<Drawable> wr = mDrawableRef;
Drawable d = null;
- if (wr != null)
+ if (wr != null) {
d = wr.get();
+ }
if (d == null) {
d = getDrawable();
@@ -119,7 +162,5 @@
return d;
}
-
- private WeakReference<Drawable> mDrawableRef;
}
diff --git a/core/java/android/text/style/IconMarginSpan.java b/core/java/android/text/style/IconMarginSpan.java
index 304c83f..ad78bd5 100644
--- a/core/java/android/text/style/IconMarginSpan.java
+++ b/core/java/android/text/style/IconMarginSpan.java
@@ -16,57 +16,98 @@
package android.text.style;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Px;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.Layout;
import android.text.Spanned;
-public class IconMarginSpan
-implements LeadingMarginSpan, LineHeightSpan
-{
- public IconMarginSpan(Bitmap b) {
- mBitmap = b;
+/**
+ * Paragraph affecting span, that draws a bitmap at the beginning of a text. The span also allows
+ * setting a padding between the bitmap and the text. The default value of the padding is 0px. The
+ * span should be attached from the first character of the text.
+ * <p>
+ * For example, an <code>IconMarginSpan</code> with a bitmap and a padding of 30px can be set
+ * like this:
+ * <pre>
+ * SpannableString string = new SpannableString("Text with icon and padding");
+ * string.setSpan(new IconMarginSpan(bitmap, 30), 0, string.length(),
+ * Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * </pre>
+ * <img src="{@docRoot}reference/android/images/text/style/iconmarginspan.png" />
+ * <figcaption>Text with <code>IconMarginSpan</code></figcaption>
+ * <p>
+ *
+ * @see DrawableMarginSpan for working with a {@link android.graphics.drawable.Drawable} instead of
+ * a {@link Bitmap}.
+ */
+public class IconMarginSpan implements LeadingMarginSpan, LineHeightSpan {
+
+ @NonNull
+ private final Bitmap mBitmap;
+ @Px
+ private final int mPad;
+
+ /**
+ * Creates an {@link IconMarginSpan} from a {@link Bitmap}.
+ *
+ * @param bitmap bitmap to be rendered at the beginning of the text
+ */
+ public IconMarginSpan(@NonNull Bitmap bitmap) {
+ this(bitmap, 0);
}
- public IconMarginSpan(Bitmap b, int pad) {
- mBitmap = b;
+ /**
+ * Creates an {@link IconMarginSpan} from a {@link Bitmap}.
+ *
+ * @param bitmap bitmap to be rendered at the beginning of the text
+ * @param pad padding width, in pixels, between the bitmap and the text
+ */
+ public IconMarginSpan(@NonNull Bitmap bitmap, @IntRange(from = 0) int pad) {
+ mBitmap = bitmap;
mPad = pad;
}
+ @Override
public int getLeadingMargin(boolean first) {
return mBitmap.getWidth() + mPad;
}
+ @Override
public void drawLeadingMargin(Canvas c, Paint p, int x, int dir,
- int top, int baseline, int bottom,
- CharSequence text, int start, int end,
- boolean first, Layout layout) {
+ int top, int baseline, int bottom,
+ CharSequence text, int start, int end,
+ boolean first, Layout layout) {
int st = ((Spanned) text).getSpanStart(this);
int itop = layout.getLineTop(layout.getLineForOffset(st));
- if (dir < 0)
+ if (dir < 0) {
x -= mBitmap.getWidth();
+ }
c.drawBitmap(mBitmap, x, itop, p);
}
+ @Override
public void chooseHeight(CharSequence text, int start, int end,
- int istartv, int v,
- Paint.FontMetricsInt fm) {
+ int istartv, int v,
+ Paint.FontMetricsInt fm) {
if (end == ((Spanned) text).getSpanEnd(this)) {
int ht = mBitmap.getHeight();
int need = ht - (v + fm.descent - fm.ascent - istartv);
- if (need > 0)
+ if (need > 0) {
fm.descent += need;
+ }
need = ht - (v + fm.bottom - fm.top - istartv);
- if (need > 0)
+ if (need > 0) {
fm.bottom += need;
+ }
}
}
- private Bitmap mBitmap;
- private int mPad;
}
diff --git a/core/java/android/text/style/ImageSpan.java b/core/java/android/text/style/ImageSpan.java
index b0bff68..95f0b43 100644
--- a/core/java/android/text/style/ImageSpan.java
+++ b/core/java/android/text/style/ImageSpan.java
@@ -17,6 +17,8 @@
package android.text.style;
import android.annotation.DrawableRes;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -27,18 +29,49 @@
import java.io.InputStream;
+/**
+ * Span that replaces the text it's attached to with a {@link Drawable} that can be aligned with
+ * the bottom or with the baseline of the surrounding text. The drawable can be constructed from
+ * varied sources:
+ * <ul>
+ * <li>{@link Bitmap} - see {@link #ImageSpan(Context, Bitmap)} and
+ * {@link #ImageSpan(Context, Bitmap, int)}
+ * </li>
+ * <li>{@link Drawable} - see {@link #ImageSpan(Drawable, int)}</li>
+ * <li>resource id - see {@link #ImageSpan(Context, int, int)}</li>
+ * <li>{@link Uri} - see {@link #ImageSpan(Context, Uri, int)}</li>
+ * </ul>
+ * The default value for the vertical alignment is {@link DynamicDrawableSpan#ALIGN_BOTTOM}
+ * <p>
+ * For example, an <code>ImagedSpan</code> can be used like this:
+ * <pre>
+ * SpannableString string = SpannableString("Bottom: span.\nBaseline: span.");
+ * // using the default alignment: ALIGN_BOTTOM
+ * string.setSpan(ImageSpan(this, R.mipmap.ic_launcher), 7, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * string.setSpan(ImageSpan(this, R.mipmap.ic_launcher, DynamicDrawableSpan.ALIGN_BASELINE),
+ * 22, 23, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * </pre>
+ * <img src="{@docRoot}reference/android/images/text/style/imagespan.png" />
+ * <figcaption>Text with <code>ImageSpan</code>s aligned bottom and baseline.</figcaption>
+ */
public class ImageSpan extends DynamicDrawableSpan {
+
+ @Nullable
private Drawable mDrawable;
+ @Nullable
private Uri mContentUri;
+ @DrawableRes
private int mResourceId;
+ @Nullable
private Context mContext;
+ @Nullable
private String mSource;
/**
* @deprecated Use {@link #ImageSpan(Context, Bitmap)} instead.
*/
@Deprecated
- public ImageSpan(Bitmap b) {
+ public ImageSpan(@NonNull Bitmap b) {
this(null, b, ALIGN_BOTTOM);
}
@@ -46,80 +79,143 @@
* @deprecated Use {@link #ImageSpan(Context, Bitmap, int)} instead.
*/
@Deprecated
- public ImageSpan(Bitmap b, int verticalAlignment) {
+ public ImageSpan(@NonNull Bitmap b, int verticalAlignment) {
this(null, b, verticalAlignment);
}
- public ImageSpan(Context context, Bitmap b) {
- this(context, b, ALIGN_BOTTOM);
+ /**
+ * Constructs an {@link ImageSpan} from a {@link Context} and a {@link Bitmap} with the default
+ * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}
+ *
+ * @param context context used to create a drawable from {@param bitmap} based on the display
+ * metrics of the resources
+ * @param bitmap bitmap to be rendered
+ */
+ public ImageSpan(@NonNull Context context, @NonNull Bitmap bitmap) {
+ this(context, bitmap, ALIGN_BOTTOM);
}
/**
+ * Constructs an {@link ImageSpan} from a {@link Context}, a {@link Bitmap} and a vertical
+ * alignment.
+ *
+ * @param context context used to create a drawable from {@param bitmap} based on
+ * the display metrics of the resources
+ * @param bitmap bitmap to be rendered
* @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
- * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
+ * {@link DynamicDrawableSpan#ALIGN_BASELINE}
*/
- public ImageSpan(Context context, Bitmap b, int verticalAlignment) {
+ public ImageSpan(@NonNull Context context, @NonNull Bitmap bitmap, int verticalAlignment) {
super(verticalAlignment);
mContext = context;
mDrawable = context != null
- ? new BitmapDrawable(context.getResources(), b)
- : new BitmapDrawable(b);
+ ? new BitmapDrawable(context.getResources(), bitmap)
+ : new BitmapDrawable(bitmap);
int width = mDrawable.getIntrinsicWidth();
int height = mDrawable.getIntrinsicHeight();
- mDrawable.setBounds(0, 0, width > 0 ? width : 0, height > 0 ? height : 0);
- }
-
- public ImageSpan(Drawable d) {
- this(d, ALIGN_BOTTOM);
+ mDrawable.setBounds(0, 0, width > 0 ? width : 0, height > 0 ? height : 0);
}
/**
- * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
- * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
+ * Constructs an {@link ImageSpan} from a drawable with the default
+ * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}.
+ *
+ * @param drawable drawable to be rendered
*/
- public ImageSpan(Drawable d, int verticalAlignment) {
- super(verticalAlignment);
- mDrawable = d;
- }
-
- public ImageSpan(Drawable d, String source) {
- this(d, source, ALIGN_BOTTOM);
+ public ImageSpan(@NonNull Drawable drawable) {
+ this(drawable, ALIGN_BOTTOM);
}
/**
+ * Constructs an {@link ImageSpan} from a drawable and a vertical alignment.
+ *
+ * @param drawable drawable to be rendered
* @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
- * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
+ * {@link DynamicDrawableSpan#ALIGN_BASELINE}
*/
- public ImageSpan(Drawable d, String source, int verticalAlignment) {
+ public ImageSpan(@NonNull Drawable drawable, int verticalAlignment) {
super(verticalAlignment);
- mDrawable = d;
+ mDrawable = drawable;
+ }
+
+ /**
+ * Constructs an {@link ImageSpan} from a drawable and a source with the default
+ * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}
+ *
+ * @param drawable drawable to be rendered
+ * @param source drawable's Uri source
+ */
+ public ImageSpan(@NonNull Drawable drawable, @NonNull String source) {
+ this(drawable, source, ALIGN_BOTTOM);
+ }
+
+ /**
+ * Constructs an {@link ImageSpan} from a drawable, a source and a vertical alignment.
+ *
+ * @param drawable drawable to be rendered
+ * @param source drawable's uri source
+ * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
+ * {@link DynamicDrawableSpan#ALIGN_BASELINE}
+ */
+ public ImageSpan(@NonNull Drawable drawable, @NonNull String source, int verticalAlignment) {
+ super(verticalAlignment);
+ mDrawable = drawable;
mSource = source;
}
- public ImageSpan(Context context, Uri uri) {
+ /**
+ * Constructs an {@link ImageSpan} from a {@link Context} and a {@link Uri} with the default
+ * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}. The Uri source can be retrieved via
+ * {@link #getSource()}
+ *
+ * @param context context used to create a drawable from {@param bitmap} based on the display
+ * metrics of the resources
+ * @param uri {@link Uri} used to construct the drawable that will be rendered
+ */
+ public ImageSpan(@NonNull Context context, @NonNull Uri uri) {
this(context, uri, ALIGN_BOTTOM);
}
/**
+ * Constructs an {@link ImageSpan} from a {@link Context}, a {@link Uri} and a vertical
+ * alignment. The Uri source can be retrieved via {@link #getSource()}
+ *
+ * @param context context used to create a drawable from {@param bitmap} based on
+ * the display
+ * metrics of the resources
+ * @param uri {@link Uri} used to construct the drawable that will be rendered.
* @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
- * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
+ * {@link DynamicDrawableSpan#ALIGN_BASELINE}
*/
- public ImageSpan(Context context, Uri uri, int verticalAlignment) {
+ public ImageSpan(@NonNull Context context, @NonNull Uri uri, int verticalAlignment) {
super(verticalAlignment);
mContext = context;
mContentUri = uri;
mSource = uri.toString();
}
- public ImageSpan(Context context, @DrawableRes int resourceId) {
+ /**
+ * Constructs an {@link ImageSpan} from a {@link Context} and a resource id with the default
+ * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}
+ *
+ * @param context context used to retrieve the drawable from resources
+ * @param resourceId drawable resource id based on which the drawable is retrieved
+ */
+ public ImageSpan(@NonNull Context context, @DrawableRes int resourceId) {
this(context, resourceId, ALIGN_BOTTOM);
}
/**
+ * Constructs an {@link ImageSpan} from a {@link Context}, a resource id and a vertical
+ * alignment.
+ *
+ * @param context context used to retrieve the drawable from resources
+ * @param resourceId drawable resource id based on which the drawable is retrieved.
* @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
- * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
+ * {@link DynamicDrawableSpan#ALIGN_BASELINE}
*/
- public ImageSpan(Context context, @DrawableRes int resourceId, int verticalAlignment) {
+ public ImageSpan(@NonNull Context context, @DrawableRes int resourceId,
+ int verticalAlignment) {
super(verticalAlignment);
mContext = context;
mResourceId = resourceId;
@@ -128,10 +224,10 @@
@Override
public Drawable getDrawable() {
Drawable drawable = null;
-
+
if (mDrawable != null) {
drawable = mDrawable;
- } else if (mContentUri != null) {
+ } else if (mContentUri != null) {
Bitmap bitmap = null;
try {
InputStream is = mContext.getContentResolver().openInputStream(
@@ -142,7 +238,7 @@
drawable.getIntrinsicHeight());
is.close();
} catch (Exception e) {
- Log.e("sms", "Failed to loaded content " + mContentUri, e);
+ Log.e("ImageSpan", "Failed to loaded content " + mContentUri, e);
}
} else {
try {
@@ -150,8 +246,8 @@
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight());
} catch (Exception e) {
- Log.e("sms", "Unable to find resource: " + mResourceId);
- }
+ Log.e("ImageSpan", "Unable to find resource: " + mResourceId);
+ }
}
return drawable;
@@ -159,9 +255,12 @@
/**
* Returns the source string that was saved during construction.
+ *
+ * @return the source string that was saved during construction
+ * @see #ImageSpan(Drawable, String) and this{@link #ImageSpan(Context, Uri)}
*/
+ @Nullable
public String getSource() {
return mSource;
}
-
}
diff --git a/core/java/android/text/style/LineHeightSpan.java b/core/java/android/text/style/LineHeightSpan.java
index 1ebee82..50ee5f3 100644
--- a/core/java/android/text/style/LineHeightSpan.java
+++ b/core/java/android/text/style/LineHeightSpan.java
@@ -19,16 +19,42 @@
import android.graphics.Paint;
import android.text.TextPaint;
-public interface LineHeightSpan
-extends ParagraphStyle, WrapTogetherSpan
-{
+/**
+ * The classes that affect the height of the line should implement this interface.
+ */
+public interface LineHeightSpan extends ParagraphStyle, WrapTogetherSpan {
+ /**
+ * Classes that implement this should define how the height is being calculated.
+ *
+ * @param text the text
+ * @param start the start of the line
+ * @param end the end of the line
+ * @param spanstartv the start of the span
+ * @param lineHeight the line height
+ * @param fm font metrics of the paint, in integers
+ */
public void chooseHeight(CharSequence text, int start, int end,
- int spanstartv, int v,
- Paint.FontMetricsInt fm);
+ int spanstartv, int lineHeight,
+ Paint.FontMetricsInt fm);
+ /**
+ * The classes that affect the height of the line with respect to density, should implement this
+ * interface.
+ */
public interface WithDensity extends LineHeightSpan {
+
+ /**
+ * Classes that implement this should define how the height is being calculated.
+ *
+ * @param text the text
+ * @param start the start of the line
+ * @param end the end of the line
+ * @param spanstartv the start of the span
+ * @param lineHeight the line height
+ * @param paint the paint
+ */
public void chooseHeight(CharSequence text, int start, int end,
- int spanstartv, int v,
- Paint.FontMetricsInt fm, TextPaint paint);
+ int spanstartv, int lineHeight,
+ Paint.FontMetricsInt fm, TextPaint paint);
}
}
diff --git a/core/java/android/text/style/MaskFilterSpan.java b/core/java/android/text/style/MaskFilterSpan.java
index 2ff52a8f..d76ef94 100644
--- a/core/java/android/text/style/MaskFilterSpan.java
+++ b/core/java/android/text/style/MaskFilterSpan.java
@@ -18,15 +18,36 @@
import android.graphics.MaskFilter;
import android.text.TextPaint;
-
+/**
+ * Span that allows setting a {@link MaskFilter} to the text it's attached to.
+ * <p>
+ * For example, to blur a text, a {@link android.graphics.BlurMaskFilter} can be used:
+ * <pre>
+ * MaskFilter blurMask = new BlurMaskFilter(5f, BlurMaskFilter.Blur.NORMAL);
+ * SpannableString string = new SpannableString("Text with blur mask");
+ * string.setSpan(new MaskFilterSpan(blurMask), 10, 15, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * </pre>
+ * <img src="{@docRoot}reference/android/images/text/style/maskfilterspan.png" />
+ * <figcaption>Text blurred with the <code>MaskFilterSpan</code>.</figcaption>
+ */
public class MaskFilterSpan extends CharacterStyle implements UpdateAppearance {
private MaskFilter mFilter;
+ /**
+ * Creates a {@link MaskFilterSpan} from a {@link MaskFilter}.
+ *
+ * @param filter the filter to be applied to the <code>TextPaint</code>
+ */
public MaskFilterSpan(MaskFilter filter) {
mFilter = filter;
}
+ /**
+ * Return the mask filter for this span.
+ *
+ * @return the mask filter for this span
+ */
public MaskFilter getMaskFilter() {
return mFilter;
}
diff --git a/core/java/android/text/style/StyleSpan.java b/core/java/android/text/style/StyleSpan.java
index f900db5..bdfa700 100644
--- a/core/java/android/text/style/StyleSpan.java
+++ b/core/java/android/text/style/StyleSpan.java
@@ -16,6 +16,7 @@
package android.text.style;
+import android.annotation.NonNull;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Parcel;
@@ -24,55 +25,76 @@
import android.text.TextUtils;
/**
- *
- * Describes a style in a span.
+ * Span that allows setting the style of the text it's attached to.
+ * Possible styles are: {@link Typeface#NORMAL}, {@link Typeface#BOLD}, {@link Typeface#ITALIC} and
+ * {@link Typeface#BOLD_ITALIC}.
+ * <p>
* Note that styles are cumulative -- if both bold and italic are set in
* separate spans, or if the base style is bold and a span calls for italic,
* you get bold italic. You can't turn off a style from the base style.
- *
+ * <p>
+ * For example, the <code>StyleSpan</code> can be used like this:
+ * <pre>
+ * SpannableString string = new SpannableString("Bold and italic text");
+ * string.setSpan(new StyleSpan(Typeface.BOLD), 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * string.setSpan(new StyleSpan(Typeface.ITALIC), 9, 15, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * </pre>
+ * <img src="{@docRoot}reference/android/images/text/style/stylespan.png" />
+ * <figcaption>Text styled bold and italic with the <code>StyleSpan</code>.</figcaption>
*/
public class StyleSpan extends MetricAffectingSpan implements ParcelableSpan {
private final int mStyle;
/**
- *
+ * Creates a {@link StyleSpan} from a style.
+ *
* @param style An integer constant describing the style for this span. Examples
- * include bold, italic, and normal. Values are constants defined
- * in {@link android.graphics.Typeface}.
+ * include bold, italic, and normal. Values are constants defined
+ * in {@link Typeface}.
*/
public StyleSpan(int style) {
mStyle = style;
}
- public StyleSpan(Parcel src) {
+ /**
+ * Creates a {@link StyleSpan} from a parcel.
+ *
+ * @param src the parcel
+ */
+ public StyleSpan(@NonNull Parcel src) {
mStyle = src.readInt();
}
-
+
+ @Override
public int getSpanTypeId() {
return getSpanTypeIdInternal();
}
/** @hide */
+ @Override
public int getSpanTypeIdInternal() {
return TextUtils.STYLE_SPAN;
}
-
+
+ @Override
public int describeContents() {
return 0;
}
+ @Override
public void writeToParcel(Parcel dest, int flags) {
writeToParcelInternal(dest, flags);
}
/** @hide */
- public void writeToParcelInternal(Parcel dest, int flags) {
+ @Override
+ public void writeToParcelInternal(@NonNull Parcel dest, int flags) {
dest.writeInt(mStyle);
}
/**
- * Returns the style constant defined in {@link android.graphics.Typeface}.
+ * Returns the style constant defined in {@link Typeface}.
*/
public int getStyle() {
return mStyle;
diff --git a/core/java/android/text/style/TabStopSpan.java b/core/java/android/text/style/TabStopSpan.java
index 0566428..2cceb2c 100644
--- a/core/java/android/text/style/TabStopSpan.java
+++ b/core/java/android/text/style/TabStopSpan.java
@@ -16,39 +16,54 @@
package android.text.style;
+import android.annotation.IntRange;
+import android.annotation.Px;
+
/**
- * Represents a single tab stop on a line.
+ * Paragraph affecting span that changes the position of the tab with respect to
+ * the leading margin of the line. <code>TabStopSpan</code> will only affect the first tab
+ * encountered on the first line of the text.
*/
-public interface TabStopSpan
-extends ParagraphStyle
-{
- /**
- * Returns the offset of the tab stop from the leading margin of the
- * line.
- * @return the offset
- */
- public int getTabStop();
+public interface TabStopSpan extends ParagraphStyle {
/**
- * The default implementation of TabStopSpan.
+ * Returns the offset of the tab stop from the leading margin of the line, in pixels.
+ *
+ * @return the offset, in pixels
*/
- public static class Standard
- implements TabStopSpan
- {
+ int getTabStop();
+
+ /**
+ * The default implementation of TabStopSpan that allows setting the offset of the tab stop
+ * from the leading margin of the first line of text.
+ * <p>
+ * Let's consider that we have the following text: <i>"\tParagraph text beginning with tab."</i>
+ * and we want to move the tab stop with 100px. This can be achieved like this:
+ * <pre>
+ * SpannableString string = new SpannableString("\tParagraph text beginning with tab.");
+ * string.setSpan(new TabStopSpan.Standard(100), 0, string.length(),
+ * Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);</pre>
+ * <img src="{@docRoot}reference/android/images/text/style/tabstopspan.png" />
+ * <figcaption>Text with a tab stop and a <code>TabStopSpan</code></figcaption>
+ */
+ class Standard implements TabStopSpan {
+
+ @Px
+ private int mTabOffset;
+
/**
- * Constructor.
+ * Constructs a {@link TabStopSpan.Standard} based on an offset.
*
- * @param where the offset of the tab stop from the leading margin of
- * the line
+ * @param offset the offset of the tab stop from the leading margin of
+ * the line, in pixels
*/
- public Standard(int where) {
- mTab = where;
+ public Standard(@IntRange(from = 0) int offset) {
+ mTabOffset = offset;
}
+ @Override
public int getTabStop() {
- return mTab;
+ return mTabOffset;
}
-
- private int mTab;
}
}
diff --git a/core/java/android/text/style/TypefaceSpan.java b/core/java/android/text/style/TypefaceSpan.java
index aa622d8..1622812 100644
--- a/core/java/android/text/style/TypefaceSpan.java
+++ b/core/java/android/text/style/TypefaceSpan.java
@@ -16,6 +16,7 @@
package android.text.style;
+import android.annotation.NonNull;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Parcel;
@@ -24,42 +25,59 @@
import android.text.TextUtils;
/**
- * Changes the typeface family of the text to which the span is attached.
+ * Changes the typeface family of the text to which the span is attached. Examples of typeface
+ * family include "monospace", "serif", and "sans-serif".
+ * <p>
+ * For example, change the typeface of a text to "monospace" like this:
+ * <pre>
+ * SpannableString string = new SpannableString("Text with typeface span");
+ * string.setSpan(new TypefaceSpan("monospace"), 10, 18, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * </pre>
+ * <img src="{@docRoot}reference/android/images/text/style/typefacespan.png" />
+ * <figcaption>Text with "monospace" typeface family.</figcaption>
*/
public class TypefaceSpan extends MetricAffectingSpan implements ParcelableSpan {
+
private final String mFamily;
/**
- * @param family The font family for this typeface. Examples include
- * "monospace", "serif", and "sans-serif".
+ * Constructs a {@link TypefaceSpan} based on a font family.
+ *
+ * @param family The font family for this typeface. Examples include
+ * "monospace", "serif", and "sans-serif".
*/
public TypefaceSpan(String family) {
mFamily = family;
}
- public TypefaceSpan(Parcel src) {
+ public TypefaceSpan(@NonNull Parcel src) {
mFamily = src.readString();
}
-
+
+ @Override
public int getSpanTypeId() {
return getSpanTypeIdInternal();
}
/** @hide */
+ @Override
public int getSpanTypeIdInternal() {
return TextUtils.TYPEFACE_SPAN;
}
-
+
+ @Override
public int describeContents() {
return 0;
}
- public void writeToParcel(Parcel dest, int flags) {
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
writeToParcelInternal(dest, flags);
}
/** @hide */
- public void writeToParcelInternal(Parcel dest, int flags) {
+ @Override
+ public void writeToParcelInternal(@NonNull Parcel dest, int flags) {
dest.writeString(mFamily);
}
@@ -71,16 +89,16 @@
}
@Override
- public void updateDrawState(TextPaint ds) {
- apply(ds, mFamily);
+ public void updateDrawState(@NonNull TextPaint textPaint) {
+ apply(textPaint, mFamily);
}
@Override
- public void updateMeasureState(TextPaint paint) {
- apply(paint, mFamily);
+ public void updateMeasureState(@NonNull TextPaint textPaint) {
+ apply(textPaint, mFamily);
}
- private static void apply(Paint paint, String family) {
+ private static void apply(@NonNull Paint paint, String family) {
int oldStyle;
Typeface old = paint.getTypeface();
diff --git a/core/java/android/text/style/URLSpan.java b/core/java/android/text/style/URLSpan.java
index 58239ef..eab1ef4 100644
--- a/core/java/android/text/style/URLSpan.java
+++ b/core/java/android/text/style/URLSpan.java
@@ -16,6 +16,7 @@
package android.text.style;
+import android.annotation.NonNull;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
@@ -27,40 +28,71 @@
import android.util.Log;
import android.view.View;
+/**
+ * Implementation of the {@link ClickableSpan} that allows setting a url string. When
+ * selecting and clicking on the text to which the span is attached, the <code>URLSpan</code>
+ * will try to open the url, by launching an an Activity with an {@link Intent#ACTION_VIEW} intent.
+ * <p>
+ * For example, a <code>URLSpan</code> can be used like this:
+ * <pre>
+ * SpannableString string = new SpannableString("Text with a url span");
+ * string.setSpan(new URLSpan("http://www.developer.android.com"), 12, 15, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ * </pre>
+ * <img src="{@docRoot}reference/android/images/text/style/urlspan.png" />
+ * <figcaption>Text with <code>URLSpan</code>.</figcaption>
+ */
public class URLSpan extends ClickableSpan implements ParcelableSpan {
private final String mURL;
+ /**
+ * Constructs a {@link URLSpan} from a url string.
+ *
+ * @param url the url string
+ */
public URLSpan(String url) {
mURL = url;
}
- public URLSpan(Parcel src) {
+ /**
+ * Constructs a {@link URLSpan} from a parcel.
+ */
+ public URLSpan(@NonNull Parcel src) {
mURL = src.readString();
}
-
+
+ @Override
public int getSpanTypeId() {
return getSpanTypeIdInternal();
}
/** @hide */
+ @Override
public int getSpanTypeIdInternal() {
return TextUtils.URL_SPAN;
}
-
+
+ @Override
public int describeContents() {
return 0;
}
- public void writeToParcel(Parcel dest, int flags) {
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
writeToParcelInternal(dest, flags);
}
/** @hide */
- public void writeToParcelInternal(Parcel dest, int flags) {
+ @Override
+ public void writeToParcelInternal(@NonNull Parcel dest, int flags) {
dest.writeString(mURL);
}
+ /**
+ * Get the url string for this span.
+ *
+ * @return the url string.
+ */
public String getURL() {
return mURL;
}
diff --git a/docs/html/reference/images/text/style/drawablemarginspan.png b/docs/html/reference/images/text/style/drawablemarginspan.png
new file mode 100644
index 0000000..edf926d
--- /dev/null
+++ b/docs/html/reference/images/text/style/drawablemarginspan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/dynamicdrawablespan.png b/docs/html/reference/images/text/style/dynamicdrawablespan.png
new file mode 100644
index 0000000..8776b03
--- /dev/null
+++ b/docs/html/reference/images/text/style/dynamicdrawablespan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/iconmarginspan.png b/docs/html/reference/images/text/style/iconmarginspan.png
new file mode 100644
index 0000000..8ec39be
--- /dev/null
+++ b/docs/html/reference/images/text/style/iconmarginspan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/imagespan.png b/docs/html/reference/images/text/style/imagespan.png
new file mode 100644
index 0000000..c03e6bb
--- /dev/null
+++ b/docs/html/reference/images/text/style/imagespan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/maskfilterspan.png b/docs/html/reference/images/text/style/maskfilterspan.png
new file mode 100644
index 0000000..6e55dbc
--- /dev/null
+++ b/docs/html/reference/images/text/style/maskfilterspan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/stylespan.png b/docs/html/reference/images/text/style/stylespan.png
new file mode 100644
index 0000000..9ffa05b
--- /dev/null
+++ b/docs/html/reference/images/text/style/stylespan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/tabstopspan.png b/docs/html/reference/images/text/style/tabstopspan.png
new file mode 100644
index 0000000..89a1121
--- /dev/null
+++ b/docs/html/reference/images/text/style/tabstopspan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/typefacespan.png b/docs/html/reference/images/text/style/typefacespan.png
new file mode 100644
index 0000000..67e2cf9
--- /dev/null
+++ b/docs/html/reference/images/text/style/typefacespan.png
Binary files differ
diff --git a/docs/html/reference/images/text/style/urlspan.png b/docs/html/reference/images/text/style/urlspan.png
new file mode 100644
index 0000000..1134520
--- /dev/null
+++ b/docs/html/reference/images/text/style/urlspan.png
Binary files differ