Search code examples
javaandroidstringtextview

Align one string on the left and second one on the right side of textView


I'm facing little problem with proper alignment of strings in my TextView. I have 2 strings (left and right) and TextView that has match_parent width. The point is that every solution I find doesn't worked (or doesn't work as I want).

Here's my code:

        String LeftText = "Left";
        String RightText = "Right";
        SpannableString finalString = new SpannableString(LeftText+ " " + RightText);
        finalString.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE), LeftText.length() , LeftText.length() +RightText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        textView.setText(finalString);

I find similar code that works here: solution that works partly but there is new line sing "\n". I noticed that If I replace " " with "\n" "right" String is on the right side of TextView but little lower (because of the new line sing) but I want this whole text to be in the same line. Can I do something about this?


Solution

  • If you want to achieve this in a single TextView without splitting it into two, you can try something like this:

    String leftText = "Left";
    String rightText = "Right";
    SpannableString finalString = new SpannableString(leftText+ " " + rightText);
    
    Drawable drawable = new ColorDrawable(Color.TRANSPARENT);
    
    textView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            textView.getViewTreeObserver().removeOnPreDrawListener(this);
    
            float textViewContentWidth = textView.getWidth() - textView.getPaddingStart() - textView.getCompoundPaddingEnd();
            float leftTextWidth = textView.getPaint().measureText(leftText);
            float rightTextWidth = textView.getPaint().measureText(rightText);
    
            drawable.setBounds(0, 0, (int)(textViewContentWidth - rightTextWidth - leftTextWidth), 1);
    
            finalString.setSpan(new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE), leftText.length(), leftText.length() + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    
            textView.setText(finalString);
            return true;
        }
    });
    

    The idea is as follows (assuming that the left and right texts do not overlap):

    1. Concatenate strings with a space, as in the original question.
    2. Measure the distance between the left and right texts and create a transparent drawable of this width.
    3. Use ImageSpan to replace the space from step 1.