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

前端 未结 6 1421
南旧
南旧 2020-12-04 20:37

I have this TextView. Some parts of it is supposed to be aligned to the left and some parts to the right. How would I do this in Java?

Basicly I want t

相关标签:
6条回答
  • 2020-12-04 20:43

    Inspired other solutions, but resolving multiline text issues and text overlap issue.

    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
            }
        }
    
    }
    

    Usage:

    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 solution is using Kpan library https://github.com/2dxgujun/Kpan

    0 讨论(0)
  • 2020-12-04 20:49

    Here is a solution that works with Spannable, with the cavate that if the right and left are too wide, they will overlap on the same line. Since to do the Left/Right trick with a spannable requires a line feed between Left and Right, my fix is to add a spannable that reduces the line height to zero (i.e. overlapped lines) for the one linefeed and then restore normal line height after that.

        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);
    

    And we have the small routine to handle the overlapping lines:

        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;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-04 20:51

    Thanks for the tip, @Frank, but this was just enough:

    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;
        }
    }
    

    Used like this:

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

    where Truss is

    A SpannableStringBuilder wrapper whose API doesn't make me want to stab my eyes out.

    • Jake Wharton, https://gist.github.com/JakeWharton/11274467
    0 讨论(0)
  • 2020-12-04 20:53

    Simple.Adjust xml part in textview. Use layouts.If you want the textview to be in left

    android:alignParentLeft="true" For more align details look this.

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

    And this is also an example for different layouts.

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

    0 讨论(0)
  • 2020-12-04 21:00
    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.

    0 讨论(0)
  • 2020-12-04 21:00

    Two solution :

    1) have a different text view for each line and set its gravity.

    2) Use Html while loading data setting the alignment in html for it REF:how-to-display-html-in-textview This will not work align is not a supported tags Edited:

    Also

    3: will be to use a span.

    0 讨论(0)
提交回复
热议问题