/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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;

A span which adds a drawable and a padding to the paragraph it's attached to.

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. DrawableMarginSpan 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.

For example, a drawable and a padding of 20px can be added like this:

SpannableString string = new SpannableString("Text with a drawable.");
string.setSpan(new DrawableMarginSpan(drawable, 20), 0, string.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
Text with a drawable and a padding.

See Also:
/** * 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 DrawableMarginSpan from a Drawable. The pad width will be 0.
Params:
  • drawable – the drawable to be added
/** * 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); }
Creates a DrawableMarginSpan from a Drawable and a padding, in pixels.
Params:
  • drawable – the drawable to be added
  • pad – the distance between the drawable and the text
/** * 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; } @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 dw = mDrawable.getIntrinsicWidth(); int dh = mDrawable.getIntrinsicHeight(); // XXX What to do about Paint? mDrawable.setBounds(ix, itop, ix + dw, itop + dh); mDrawable.draw(c); } @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) { fm.descent += need; } need = ht - (v + fm.bottom - fm.top - istartv); if (need > 0) { fm.bottom += need; } } } }