Android Indent and Hanging Indent
Asked Answered
C

1

8

I am interested in having a series of TextViews, ultimately with a hanging indent. The standard way of doing this via CSS is to set the margin to X pixels and then set the text indent to -X pixels. Obviously I can do the first with "android:layout_marginLeft="Xdp", but I'm not sure how to impose the -X pixels on the TextView. Any ideas or workarounds? I appreciate any suggestions.

Chiliasm answered 31/1, 2012 at 22:24 Comment(1)
I would suggest you generate HTML and use WebView instead.Eirena
N
13

Figured out how to make hanging indents work for my own project. Basically you need to use android.text.style.LeadingMarginSpan, and apply it to your text via code. LeadingMarginSpan.Standard takes either a full indent (1 param) or a hanging indent (2 params) constructor, and you need to create a new Span object for each substring that you want to apply the style to. The TextView itself will also need to have its BufferType set to SPANNABLE.

If you have to do this multiple times, or want to incorporate indents in your style, try creating a subclass of TextView that takes a custom indent attribute and applies the span automatically. I've gotten a lot of use out of this Custom Views & XML attributes tutorial from the Statically Typed blog, and the SO question Declaring a custom android UI element using XML.

In TextView:

// android.text.style.CharacterStyle is a basic interface, you can try the 
// TextAppearanceSpan class to pull from an existing style/theme in XML

CharacterStyle style_char = 
    new TextAppearanceSpan (getContext(), styleId);
float textSize = style_char.getTextSize();

// indentF roughly corresponds to ems in dp after accounting for 
// system/base font scaling, you'll need to tweak it

float indentF = 1.0f;
int indent = (int) indentF;
if (textSize > 0) {
    indent = (int) indentF * textSize;
}

// android.text.style.ParagraphStyle is a basic interface, but
// LeadingMarginSpan handles indents/margins
// If you're API8+, there's also LeadingMarginSpan2, which lets you 
// specify how many lines to count as "first line hanging"

ParagraphStyle style_para = new LeadingMarginSpan.Standard (indent);

String unstyledSource = this.getText();

// SpannableString has mutable markup, with fixed text
// SpannableStringBuilder has mutable markup and mutable text

SpannableString styledSource = new SpannableString (unstyledSource);
styledSource.setSpan (style_char, 0, styledSource.length(), 
        Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
styledSource.setSpan (style_para, 0, styledSource.length(),
        Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

// *or* you can use Spanned.SPAN_PARAGRAPH for style_para, but check
// the docs for usage

this.setText (styledSource, BufferType.SPANNABLE);
Nablus answered 31/5, 2012 at 18:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.