Подтвердить что ты не робот

Сделайте определенную часть андроида-textview вправо

У меня есть это TextView. Некоторые его части должны быть выровнены влево, а некоторые - вправо. Как мне это сделать на Java?

В основном я хочу, чтобы первая строка выравнивалась влево, а следующая строка - вправо и т.д.

Кто-нибудь понял?

ИЗМЕНИТЬ

Я попытался использовать HTML, а затем, когда это не помогло, я пробовал пробелы.

html попытка

textView.setText(Html.fromHtml("<p align=\"right\">THIS IS TO THE RIGHT</p>"));

И вот попытка пролета

    String LeftText = "LEFT";
    String RightText = "RIGHT";

    final String resultText = LeftText + "  " + RightText;
    final SpannableString styledResultText = new SpannableString(resultText);
    styledResultText.setSpan(new AlignmentSpan.Standard(Alignment.ALIGN_OPPOSITE), LeftText.length() + 1, LeftText.length() + 2 +RightText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    textView.setText(styledResultText);

Но никто из них не работает.

4b9b3361

Ответ 1

TextView resultTextView = new TextView(this);
final String resultText = LeftText + "  " + RightText;
final SpannableString styledResultText = new SpannableString(resultText);
styledResultText.setSpan(new AlignmentSpan.Standard(Alignment.ALIGN_OPPOSITE)
    , LeftText.length() + 2
    , LeftText.length() + 2 + RightText.length()
    , Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
resultTextView.setText(styledResultText);

Alignment.ALIGN_OPPOSITE is the equivalent for right side.

Alignment.ALIGN_NORMAL is the equivalent for left side.

Ответ 2

Вот решение, которое работает с Spannable, с каватетом, если справа и слева слишком широкие, они будут перекрываться на одной линии. Поскольку для выполнения левого/правого трюка с помощью spannable требуется прямая линия между Left и Right, мое исправление заключается в добавлении spannable, который уменьшает высоту линии до нуля (т.е. перекрывающиеся линии) для одного перевода строки, а затем восстанавливает нормальную высоту линии после что.

    String fullText = leftText + "\n " + rightText;     // only works if  linefeed between them! "\n ";

    int fullTextLength = fullText.length();
    int leftEnd = leftText.length();
    int rightTextLength = rightText.length();

    final SpannableString s = new SpannableString(fullText);
    AlignmentSpan alignmentSpan = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE);
    s.setSpan(alignmentSpan, leftEnd, fullTextLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    s.setSpan(new SetLineOverlap(true), 1, fullTextLength-2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    s.setSpan(new SetLineOverlap(false), fullTextLength-1, fullTextLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

И у нас есть небольшая подпрограмма для обработки перекрывающихся строк:

    private static class SetLineOverlap implements LineHeightSpan {
    private int originalBottom = 15;        // init value ignored
    private int originalDescent = 13;       // init value ignored
    private Boolean overlap;                // saved state
    private Boolean overlapSaved = false;   // ensure saved values only happen once

    SetLineOverlap(Boolean overlap) {
        this.overlap = overlap;
    }

    @Override
    public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v,
                             Paint.FontMetricsInt fm) {
        if (overlap) {
            if (!overlapSaved) {
                originalBottom = fm.bottom;
                originalDescent = fm.descent;
                overlapSaved = true;
            }
            fm.bottom += fm.top;
            fm.descent += fm.top;
        } else {
            // restore saved values
            fm.bottom = originalBottom;
            fm.descent = originalDescent;
            overlapSaved = false;
        }
    }
}

Ответ 3

Спасибо за подсказку @Frank, но этого было достаточно:

public class LineOverlapSpan implements LineHeightSpan {
    @Override
    public void chooseHeight(final CharSequence text, final int start, final int end, final int spanstartv, final int v, final Paint.FontMetricsInt fm) {
        fm.bottom += fm.top;
        fm.descent += fm.top;
    }
}

Используется следующим образом:

CharSequence text = return new Truss()
        .append("LEFT")
        .pushSpan(LineOverlapSpan())
        .append("\n")
        .popSpan()
        .pushSpan(AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE))
        .append("RIGHT")
        .build()

где Truss есть

A SpannableStringBuilder обертка, API которой не заставляет меня хотеть ударить глазами.

Ответ 4

Два решения:

1) имеют различный текстовый вид для каждой строки и устанавливают его гравитацию.

2) Используйте Html во время загрузки данных, устанавливая выравнивание в html для него REF: how-to-display-html-in-textview Это не сработает align не поддерживает тегиОтредактировано:

Кроме

3: будет использовать диапазон.

Ответ 5

Простой .Adjust xml part в textview. Используйте layouts.Если вы хотите, чтобы textview находился в левом

android: alignParentLeft = "true". Для получения более подробной информации смотрите это.

http://developer.android.com/reference/android/widget/RelativeLayout.LayoutParams.html

И это также пример для разных макетов.

http://www.androidhive.info/2011/07/android-layouts-linear-layout-relative-layout-and-table-layout/

Ответ 6

Вдохновили другие решения, но решили проблемы многострочного текста и проблемы с перекрытием текста.

class LineOverlapSpan() : LineHeightSpan {
    var originalBottom: Int = 0
    var originalDescent: Int = 0
    var overlapSaved = false

    override fun chooseHeight(
        text: CharSequence?,
        start: Int,
        end: Int,
        spanstartv: Int,
        v: Int,
        fm: Paint.FontMetricsInt?
    ) {
        if (fm == null) {
            return
        }

        if (!overlapSaved) {
            originalBottom = fm.bottom
            originalDescent = fm.descent
            overlapSaved = true
        }

        if (text?.subSequence(start, end)?.endsWith("\n") == true) {
            fm.bottom += fm.top
            fm.descent += fm.top
        } else {
            fm.bottom = originalBottom
            fm.descent = originalDescent
        }
    }

}

Использование:

fun keyValueSpan(key: CharSequence, value: CharSequence) = span {
    span {
        alignment = "normal"
        +key
        span {
            textColor = Color.TRANSPARENT
            +value
        }
        span {
            +"\n"
            addSpan(LineOverlapSpan())
        }
    }
    span {
        alignment = "opposite"
        +value
    }
}

Решение Kotlin использует библиотеку Kpan https://github.com/2dxgujun/Kpan