簡體   English   中英

使 android-textview 的某個部分向右對齊

[英]Make a certain part of a android-textview align to the right

我有這個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);

但它們似乎都不起作用。

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.

這是一個與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;
        }
    }
}

謝謝你的提示@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在哪里

一個SpannableStringBuilder包裝器,它的API不會讓我想要我的眼睛。

兩個解決方案

1)為每一行提供不同的文本視圖並設置其重力。

2)在加載數據時使用Html設置html中的對齊為它REF:how-to-display-html-in-textview 這將不起作用 align不是支持的標簽編輯:

3:將使用跨度。

Simple.Adjust在textview中的xml部分。 使用layouts.If您希望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/

啟發了其他解決方案,但解決了多行文本問題和文本重疊問題

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

我不想創建自定義視圖,也無法在此處使用跨度答案,因為我想在包含列表項的對話框中實現這一點。

所以,我剛剛計算了需要在字符串中間添加多少空格才能讓我的文本填充整個父寬度並將其中的一部分向左對齊。

公式: ((width of parent - width of text) / width of single space) = number of spaces

為了計算文本寬度,我使用了如何在 Android 上獲取字符串寬度的答案?

private fun calculateTextWidthPixels(context: Context, text: String, textSizeSp: Float): Int {
    val bounds = Rect()
    val textPaint = TextPaint().apply {
        typeface = Typeface.create("sans-serif", Typeface.NORMAL)
        textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, textSizeSp, context.resources.displayMetrics)
        getTextBounds(text, 0, text.length, bounds)
    }
    return StaticLayout.getDesiredWidth(text, textPaint).toAccurateInt()
}

private fun padMiddleOfTextWithSpaces(leftText: String, rightText: String, desiredWidthPixels: Int, textSizeSp: Float): String {
    val originalText = "$leftText $rightText"
    val originalTextWidth = calculateTextWidthPixels(context, originalText, textSizeSp)
    val singleSpaceTextWidth = calculateTextWidthPixels(context, " ", textSizeSp)
    val availableWidthForSpaces = desiredWidthPixels - originalTextWidth
    val spacesRequired = " ".repeat((availableWidthForSpaces / singleSpaceTextWidth))
    return "$leftText $spacesRequired$rightText"
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM