bernardo.g
bernardo.g

Reputation: 758

How can I limit a TextView's size without using 'maxwidth'?

I've been trying to create a layout for a RecyclerView item, but I'm, having trouble getting there. I'll try my best to explain what I want and what I've gotten so far. My design has a Button, a TextView, a couple of ImageViews and a LinearLayout with some ImageViews inside it. The image below explains it well.

enter image description here

I've gotten sort of close to what I want: the blue tv and the red and green ivs are inside a LinearLayout with a gravity=left attribute. The blue tv has the ellipsis=end attribute. The one thing that's still wrong is the blue tv has to have a maxwidth attribute so it does not push the green/red ivs over the gray LinearLayout to the right. So, when the red or green ivs are "gone", there's an empty space to the right (before the gray LinearLayout) since the blue tv's maxwidth limits it.

Is there a way to achieve this? How can I eliminate the maxwidth attribute and still prevent the textview content from pushing the green and red ivs too far to the right and overruning the gray LinearLayout?

I don't have any experience with ConstraintLayout (and am a beginner in android development). Is there a way to achieve this using it?

Here's the code I have so far.

<LinearLayout
    android:id="@+id/leiaute"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <Button
        android:id="@+id/quad_done_undone"
        android:layout_width="17.6dp"
        android:layout_height="16dp"
        android:layout_marginLeft="14dp"
        android:src="@drawable/circulo_unchecked"/>

    <LinearLayout
        android:id="@+id/itemClickableArea"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:layout_weight="1"
        android:gravity="left|center_vertical"
        android:orientation="horizontal"
        android:background="?attr/selectableItemBackground">

        <TextView
            android:id="@+id/titulo"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:ellipsize="end"
            android:fontFamily="sans-serif"
            android:gravity="left|center_vertical"
            android:maxLines="1"
            android:maxWidth="210dp"
            android:text="Lorem Ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua"
            android:textColor="@color/preto"
            android:textSize="13sp"
            android:visibility="visible"/>

        <ImageButton
            android:id="@+id/descricao"
            android:layout_width="16dp"
            android:layout_height="13.5dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="1dp"
            android:background="@drawable/description_icon"/>

        <ImageView
            android:id="@+id/play"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="4dp"
            android:layout_marginRight="4dp"
            android:src="@drawable/play"
            android:tint="@color/cinza3"
            android:visibility="visible"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="36dp"
        android:layout_height="wrap_content"
        android:layout_marginRight="6dp"
        android:gravity="center_vertical|center_horizontal"
        android:orientation="vertical">

        <TextView
            android:id="@+id/data_hora"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:fontFamily="sans-serif"
            android:gravity="center"
            android:maxLines="2"
            android:textColor="@color/textList"
            android:textSize="12sp"
            tools:text="31 mar\n9:42"/>


        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="3dp"
            android:gravity="center_horizontal|center_vertical"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/repeat"
                android:layout_width="10dp"
                android:layout_height="10dp"
                android:layout_marginRight="2dp"
                android:src="@drawable/repeat"
                android:tint="@color/iconesList"/>


            <ImageView
                android:id="@+id/locale"
                android:layout_width="10dp"
                android:layout_height="10dp"
                android:src="@drawable/locale"
                android:tint="@color/iconesList"/>

            <ImageView
                android:id="@+id/alarm"
                android:layout_width="10dp"
                android:layout_height="10dp"
                android:layout_marginLeft="2dp"
                android:src="@drawable/alarm"
                android:tint="@color/iconesList"/>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

Upvotes: 2

Views: 3512

Answers (3)

user7010102
user7010102

Reputation:

Here is a solution with a nested LinearLayout. I have removed unnecessary parts of your code to make the answer look more clear.

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

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="40dp"
        android:layout_weight="1">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            tools:ignore="UselessParent">

            <Button
                android:layout_width="40dp"
                android:layout_height="match_parent"
                android:background="#cdcdcd" />

            <TextView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="#2d94dd"
                android:ellipsize="end"
                android:lines="1"
                android:text="Stack Overflow" />

            <ImageButton
                android:layout_width="40dp"
                android:layout_height="match_parent"
                android:background="#00c627" />

            <ImageView
                android:layout_width="40dp"
                android:layout_height="match_parent"
                android:background="#bf0e0e" />

        </LinearLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:background="#cdcdcd" />

</LinearLayout>

Upvotes: 1

Cheticamp
Cheticamp

Reputation: 62851

What you want to do can be handled easily by TableLayout and TableRow. See the following XML for a sample layout. The key to the layout is to set the TextView that holds the long text to shrink as needed android:shrinkColumns="1" and to add a Space view that will grow to fill up extra space so the LinearLayout on the right doesn't shift to the left when the TextView shrinks.

This video shows what happens as the content of the TextView changes and the other views are set to gone.

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

    <!-- TableLayout is needed to specify shrinkColumns. Ignore "Useless parent" error. -->
    <TableRow
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:ignore="UselessParent">

        <Button
            android:layout_width="80dp"
            android:layout_height="45dp"
            android:text="Button"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:background="@android:color/holo_blue_dark"
            android:ellipsize="end"
            android:gravity="center_vertical"
            android:maxLines="1"
            android:paddingEnd="8dp"
            android:paddingLeft="8dp"
            android:paddingRight="8dp"
            android:paddingStart="8dp"
            android:scrollHorizontally="true"
            android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, etc."
            android:textSize="20sp"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/imageView1"
            android:layout_width="45dp"
            android:layout_height="45dp"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:background="@android:color/holo_green_light"
            android:gravity="center"
            android:text="iv"
            android:textSize="20sp"
            android:visibility="visible"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/imageView2"
            android:layout_width="45dp"
            android:layout_height="45dp"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:background="@android:color/holo_red_dark"
            android:gravity="center"
            android:textSize="20sp"
            android:visibility="visible"
            tools:text="iv" />
<!-- Space to expand/shrink so TableRow is always width of the screen. -->
        <Space
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@android:color/transparent" />

        <LinearLayout
            android:layout_width="60dp"
            android:layout_height="45dp"
            android:background="@android:color/darker_gray"
            android:orientation="horizontal" />
    </TableRow>
</TableLayout>

Upvotes: 5

phatnhse
phatnhse

Reputation: 3940

Add this layout in your res

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

<Button
    android:layout_width="wrap_content"
    android:layout_height="60dp"
    android:background="#757575"
    android:text="bt" />

<LinearLayout
    android:layout_width="0dp"
    android:layout_height="60dp"
    android:layout_weight="1"
    android:gravity="left"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/content"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:singleLine="true"
        android:text="Lorem Ipsum is simple. Lorem Ipsum is simple. Lorem Ipsum is simple." />

    <ImageView
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:background="#4CAF50" />

    <ImageView
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:background="#F44336" />
</LinearLayout>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="60dp"
    android:background="#757575"
    android:gravity="center">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Linear layout"
        android:textAlignment="center"
        android:textColor="#FFFFFF" />
</LinearLayout>

Then try this command in your code:

    TextView textView = (TextView) findViewById(R.id.content);
    int screenWidth = yourScreenWidth();
    int buttonWidth = buttonLeft.getWidth(); 
    int linearlayoutWidth = linearlayoutRight.getWidth();
    int greeenIvWidth = greenIv.getVisibility() == View.VISIBLE ? greenIv.getWidth() : 0;
    int redIvWidth = redIv.getVisibility() == View.VISIBLE ? redIv.getWidth() : 0;
    textView.setMaxWidth(screenWidth - buttonWidth - linearlayoutWidth - greeenIvWidth - redIvWidth);

I just calculate maxWidth of TextView, so it will be matched your conditions

  • 2 green/red ImageView is on the right of your TextView when your content is short
  • TextView will take all the space if the content is long.

Upvotes: 1

Related Questions