diff options
-rw-r--r-- | api/current.txt | 4 | ||||
-rw-r--r-- | core/java/android/text/style/BulletSpan.java | 186 | ||||
-rw-r--r-- | docs/html/reference/images/text/style/custombulletspan.png | bin | 0 -> 11949 bytes | |||
-rw-r--r-- | docs/html/reference/images/text/style/defaultbulletspan.png | bin | 0 -> 6376 bytes |
4 files changed, 149 insertions, 41 deletions
diff --git a/api/current.txt b/api/current.txt index 5f153e6d91a9..a1977bf373a4 100644 --- a/api/current.txt +++ b/api/current.txt @@ -43156,9 +43156,13 @@ package android.text.style { ctor public BulletSpan(); ctor public BulletSpan(int); ctor public BulletSpan(int, int); + ctor public BulletSpan(int, int, int); ctor public BulletSpan(android.os.Parcel); method public int describeContents(); method public void drawLeadingMargin(android.graphics.Canvas, android.graphics.Paint, int, int, int, int, int, java.lang.CharSequence, int, int, boolean, android.text.Layout); + method public int getBulletRadius(); + method public int getColor(); + method public int getGapWidth(); method public int getLeadingMargin(boolean); method public int getSpanTypeId(); method public void writeToParcel(android.os.Parcel, int); diff --git a/core/java/android/text/style/BulletSpan.java b/core/java/android/text/style/BulletSpan.java index 43dd0ff52e49..70175c8611e4 100644 --- a/core/java/android/text/style/BulletSpan.java +++ b/core/java/android/text/style/BulletSpan.java @@ -16,6 +16,11 @@ package android.text.style; +import android.annotation.ColorInt; +import android.annotation.IntRange; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.Px; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; @@ -26,38 +31,108 @@ import android.text.ParcelableSpan; import android.text.Spanned; import android.text.TextUtils; +/** + * A span which styles paragraphs as bullet points (respecting layout direction). + * <p> + * BulletSpans must be attached from the first character to the last character of a single + * paragraph, otherwise the bullet point will not be displayed but the first paragraph encountered + * will have a leading margin. + * <p> + * BulletSpans allow configuring the following elements: + * <ul> + * <li><b>gap width</b> - the distance, in pixels, between the bullet point and the paragraph. + * Default value is 2px.</li> + * <li><b>color</b> - the bullet point color. By default, the bullet point color is 0 - no color, + * so it uses the TextView's text color.</li> + * <li><b>bullet radius</b> - the radius, in pixels, of the bullet point. Default value is + * 4px.</li> + * </ul> + * For example, a BulletSpan using the default values can be constructed like this: + * <pre>{@code + * SpannableString string = new SpannableString("Text with\nBullet point"); + *string.setSpan(new BulletSpan(), 10, 22, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre> + * <img src="{@docRoot}reference/android/images/text/style/defaultbulletspan.png" /> + * <figcaption>BulletSpan constructed with default values.</figcaption> + * <p> + * <p> + * To construct a BulletSpan with a gap width of 40px, green bullet point and bullet radius of + * 20px: + * <pre>{@code + * SpannableString string = new SpannableString("Text with\nBullet point"); + *string.setSpan(new BulletSpan(40, color, 20), 10, 22, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre> + * <img src="{@docRoot}reference/android/images/text/style/custombulletspan.png" /> + * <figcaption>Customized BulletSpan.</figcaption> + */ public class BulletSpan implements LeadingMarginSpan, ParcelableSpan { - private final int mGapWidth; - private final boolean mWantColor; - private final int mColor; - // Bullet is slightly bigger to avoid aliasing artifacts on mdpi devices. - private static final float BULLET_RADIUS = 3 * 1.2f; - private static Path sBulletPath = null; + private static final int STANDARD_BULLET_RADIUS = 4; public static final int STANDARD_GAP_WIDTH = 2; + private static final int STANDARD_COLOR = 0; + @Px + private final int mGapWidth; + @Px + private final int mBulletRadius; + private Path mBulletPath = null; + @ColorInt + private final int mColor; + private final boolean mWantColor; + + /** + * Creates a {@link BulletSpan} with the default values. + */ public BulletSpan() { - mGapWidth = STANDARD_GAP_WIDTH; - mWantColor = false; - mColor = 0; + this(STANDARD_GAP_WIDTH, STANDARD_COLOR, false, STANDARD_BULLET_RADIUS); } + /** + * Creates a {@link BulletSpan} based on a gap width + * + * @param gapWidth the distance, in pixels, between the bullet point and the paragraph. + */ public BulletSpan(int gapWidth) { - mGapWidth = gapWidth; - mWantColor = false; - mColor = 0; + this(gapWidth, STANDARD_COLOR, false, STANDARD_BULLET_RADIUS); } - public BulletSpan(int gapWidth, int color) { + /** + * Creates a {@link BulletSpan} based on a gap width and a color integer. + * + * @param gapWidth the distance, in pixels, between the bullet point and the paragraph. + * @param color the bullet point color, as a color integer + * @see android.content.res.Resources#getColor(int, Resources.Theme) + */ + public BulletSpan(int gapWidth, @ColorInt int color) { + this(gapWidth, color, true, STANDARD_BULLET_RADIUS); + } + + /** + * Creates a {@link BulletSpan} based on a gap width and a color integer. + * + * @param gapWidth the distance, in pixels, between the bullet point and the paragraph. + * @param color the bullet point color, as a color integer. + * @param bulletRadius the radius of the bullet point, in pixels. + * @see android.content.res.Resources#getColor(int, Resources.Theme) + */ + public BulletSpan(int gapWidth, @ColorInt int color, @IntRange(from = 0) int bulletRadius) { + this(gapWidth, color, true, bulletRadius); + } + + private BulletSpan(int gapWidth, @ColorInt int color, boolean wantColor, + @IntRange(from = 0) int bulletRadius) { mGapWidth = gapWidth; - mWantColor = true; + mBulletRadius = bulletRadius; mColor = color; + mWantColor = wantColor; } - public BulletSpan(Parcel src) { + /** + * Creates a {@link BulletSpan} from a parcel. + */ + public BulletSpan(@NonNull Parcel src) { mGapWidth = src.readInt(); mWantColor = src.readInt() != 0; mColor = src.readInt(); + mBulletRadius = src.readInt(); } @Override @@ -77,68 +152,97 @@ public class BulletSpan implements LeadingMarginSpan, ParcelableSpan { } @Override - public void writeToParcel(Parcel dest, int flags) { + public void writeToParcel(@NonNull Parcel dest, int flags) { writeToParcelInternal(dest, flags); } /** @hide */ @Override - public void writeToParcelInternal(Parcel dest, int flags) { + public void writeToParcelInternal(@NonNull Parcel dest, int flags) { dest.writeInt(mGapWidth); dest.writeInt(mWantColor ? 1 : 0); dest.writeInt(mColor); + dest.writeInt(mBulletRadius); } @Override public int getLeadingMargin(boolean first) { - return (int) (2 * BULLET_RADIUS + mGapWidth); + return 2 * mBulletRadius + mGapWidth; + } + + /** + * Get the distance, in pixels, between the bullet point and the paragraph. + * + * @return the distance, in pixels, between the bullet point and the paragraph. + */ + public int getGapWidth() { + return mGapWidth; + } + + /** + * Get the radius, in pixels, of the bullet point. + * + * @return the radius, in pixels, of the bullet point. + */ + public int getBulletRadius() { + return mBulletRadius; + } + + /** + * Get the bullet point color. + * + * @return the bullet point color + */ + public int getColor() { + return mColor; } @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 l) { + public void drawLeadingMargin(@NonNull Canvas canvas, @NonNull Paint paint, int x, int dir, + int top, int baseline, int bottom, + @NonNull CharSequence text, int start, int end, + boolean first, @Nullable Layout layout) { if (((Spanned) text).getSpanStart(this) == start) { - Paint.Style style = p.getStyle(); + Paint.Style style = paint.getStyle(); int oldcolor = 0; if (mWantColor) { - oldcolor = p.getColor(); - p.setColor(mColor); + oldcolor = paint.getColor(); + paint.setColor(mColor); } - p.setStyle(Paint.Style.FILL); + paint.setStyle(Paint.Style.FILL); - if (l != null) { + if (layout != null) { // "bottom" position might include extra space as a result of line spacing // configuration. Subtract extra space in order to show bullet in the vertical // center of characters. - final int line = l.getLineForOffset(start); - bottom = bottom - l.getLineExtra(line); + final int line = layout.getLineForOffset(start); + bottom = bottom - layout.getLineExtra(line); } - final float y = (top + bottom) / 2f; + final float yPosition = (top + bottom) / 2f; + final float xPosition = x + dir * mBulletRadius; - if (c.isHardwareAccelerated()) { - if (sBulletPath == null) { - sBulletPath = new Path(); - sBulletPath.addCircle(0.0f, 0.0f, BULLET_RADIUS, Direction.CW); + if (canvas.isHardwareAccelerated()) { + if (mBulletPath == null) { + mBulletPath = new Path(); + mBulletPath.addCircle(0.0f, 0.0f, mBulletRadius, Direction.CW); } - c.save(); - c.translate(x + dir * BULLET_RADIUS, y); - c.drawPath(sBulletPath, p); - c.restore(); + canvas.save(); + canvas.translate(xPosition, yPosition); + canvas.drawPath(mBulletPath, paint); + canvas.restore(); } else { - c.drawCircle(x + dir * BULLET_RADIUS, y, BULLET_RADIUS, p); + canvas.drawCircle(xPosition, yPosition, mBulletRadius, paint); } if (mWantColor) { - p.setColor(oldcolor); + paint.setColor(oldcolor); } - p.setStyle(style); + paint.setStyle(style); } } } diff --git a/docs/html/reference/images/text/style/custombulletspan.png b/docs/html/reference/images/text/style/custombulletspan.png Binary files differnew file mode 100644 index 000000000000..251f8a13c077 --- /dev/null +++ b/docs/html/reference/images/text/style/custombulletspan.png diff --git a/docs/html/reference/images/text/style/defaultbulletspan.png b/docs/html/reference/images/text/style/defaultbulletspan.png Binary files differnew file mode 100644 index 000000000000..854143f8e7dc --- /dev/null +++ b/docs/html/reference/images/text/style/defaultbulletspan.png |