Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to style BlockQuotes in Android TextViews?

Is there a way to format the <BlockQuote> HTML tag within an Android TextView? WebViews are an option if I can easily manipulate 3 columns with images, ads and multiple vertical scrolling pages.

The text view obviously handles the tag, I get an ugly blue line to denote the blockquote. Is there a way to change the color of the line or better yet provide my own line image?

like image 691
jay1one Avatar asked Oct 10 '11 19:10

jay1one


1 Answers

If you use android.text.Html#fromHtml to build your android.text.Spannable, your blockquote will be implemented with android.text.style.QuoteSpan. It is this QuoteSpan that doesn't allow configuration.

The easiest solution would be to search for all the QuoteSpans in your Spannable and replace them:

private void replaceQuoteSpans(Spannable spannable) {
    QuoteSpan[] quoteSpans = spannable.getSpans(0, spanned.length(), QuoteSpan.class);
    for (QuoteSpan quoteSpan : quoteSpans) {
        int start = spannable.getSpanStart(quoteSpan);
        int end = spannable.getSpanEnd(quoteSpan);
        int flags = spannable.getSpanFlags(quoteSpan);
        spannable.removeSpan(quoteSpan);
        spannable.setSpan(new CustomQuoteSpan(
                MY_BACKGROUND_COLOR,
                MY_STRIPE_COLOR,
                MY_STRIPE_WIDTH,
                MY_GAP_WIDTH),
            start,
            end,
            flags);
    }
}

with a CustomQuoteSpan class like:

/**
 * android.text.style.QuoteSpan hard-codes the strip color and gap. :(
 */
public class CustomQuoteSpan implements LeadingMarginSpan, LineBackgroundSpan {
    private final int backgroundColor;
    private final int stripeColor;
    private final float stripeWidth;
    private final float gap;

    public CustomQuoteSpan(int backgroundColor, int stripeColor, float stripeWidth, float gap) {
        this.backgroundColor = backgroundColor;
        this.stripeColor = stripeColor;
        this.stripeWidth = stripeWidth;
        this.gap = gap;
    }

    @Override
    public int getLeadingMargin(boolean first) {
        return (int) (stripeWidth + gap);
    }

    @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) {
        Paint.Style style = p.getStyle();
        int paintColor = p.getColor();

        p.setStyle(Paint.Style.FILL);
        p.setColor(stripeColor);

        c.drawRect(x, top, x + dir * stripeWidth, bottom, p);

        p.setStyle(style);
        p.setColor(paintColor);
    }

    @Override
    public void drawBackground(Canvas c, Paint p, int left, int right, int top, int baseline, int bottom, CharSequence text, int start, int end, int lnum) {
        int paintColor = p.getColor();
        p.setColor(backgroundColor);
        c.drawRect(left, top, right, bottom, p);
        p.setColor(paintColor);
    }
}
like image 107
Heath Borders Avatar answered Oct 16 '22 19:10

Heath Borders