简体   繁体   中英

TextView - Move view to end

I have a TextView with multiple lines. How can I determine the space at the end to know if a view fits in there?

Example:

--------------------
| I am a multiline |
| text that has    |
| space at the     |
| end.       <View>|
--------------------

--------------------
| I am a multiline |
| text that has    |
| not enough space |
| at theeee end.   |
|            <View>|
--------------------

So I want my view to be in the bottom right corner, it should not overlay the text, but right of it if there is enough space

Basically, you need to see where does the last line's right (y-coordinate) reaches, and then calculate if the other view can fit the rest of the space exists.

I did a sample here with 2 textviews, but it can be applied to any view you wish. The xml is pretty straight farward, nothing out of the ordinary.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="kasjdf as df asd  aasdfasdff as dfa sd  sdf as df asd fa sd fa sdf as dfanas,df askdjfasjdf lkajsldkf jlaksjdfajsdkfj alskdj fklasjdflkasjdlkfdflk ajskldf" />

    <TextView
        android:id="@+id/text2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="attached text"
        android:textColor="@android:color/holo_blue_dark" />

</RelativeLayout>

The catch here, after text1 and text2 are drawn to in the layout, i'm calculating where does the last line of text1 reaches, and together with the width of text2 - see if it can fit the screen's width.

  • Only after text1 and text2 are drawn, i can check the width and right position, so i'm waiting for them both in setText2Position.
  • The catch here - adding rules to text2 according to the calculation described above.
  • If you have margins and padding to your views, it needs to be calculated as well fe, if text2 has padding, the check should be :

lastLineRight + text2.getWidth() + text2.getPaddingRight() + text2.getPaddingLeft() > screenWidth

public class MainActivity extends AppCompatActivity {

    private boolean[] areBothViewsDrawn = {false, false};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final TextView text1 = (TextView) findViewById(R.id.text1);
        final TextView text2 = (TextView) findViewById(R.id.text2);

        text1.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                text1.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                areBothViewsDrawn[0] = true;
                setText2Position(text1, text2);
            }
        });

        text2.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                text2.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                areBothViewsDrawn[1] = true;
                setText2Position(text1, text2);
            }
        });

    }

    private void setText2Position(TextView text1, TextView text2) {
        if (!areBothViewsDrawn[0] || !areBothViewsDrawn[1])
            return;

        int lineCount = text1.getLayout().getLineCount();
        float lastLineRight = text1.getLayout().getLineRight(lineCount - 1);

        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        int screenWidth = size.x;

        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) text2.getLayoutParams();
        if (lastLineRight + text2.getWidth() > screenWidth) {
            //The width of the last line of text1 is too long for the text2 to fit, so text2 must be in another line
            params.addRule(RelativeLayout.BELOW, text1.getId());
        } else {
            //The width of the last line of text1 and text2 smaller then the application's width, so text2 can be in the same line as text1
            params.addRule(RelativeLayout.ALIGN_BOTTOM, text1.getId());
        }
    }
}

Here are some poc's for my code :

底部

对

I think this question needs more context. (just curious to why you'd want to do this)

Something like this is possible and would be easier if the TextView had a set width/height defined in the XML. If you're just dynamically getting the information there's some steps you'd have to take to make sure you're getting the correct measurements.

One approach I'm thinking would be to get the entire TextView's width, and get the difference between that and the actual text's width (perhaps a combination of getLineCount()/getLineBounds(int, Rect?) and getTextScaleX() ?). Then convert it to dp .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM