【问题标题】:Android layout how to horizontal align textView with dynamical widthAndroid布局如何将textView与动态宽度水平对齐
【发布时间】:2019-12-21 07:42:29
【问题描述】:

有 4 个视图 A (TextView)、B(icon)、C(TextView)、D (TextView) 水平对齐彼此相邻。

B 和 D 具有固定宽度。文字会填充到onBindView()中。

可以根据屏幕方向计算其父级的宽度。

它需要尽可能多地显示 A,C 将消耗其余部分或直到其内容宽度(如果空间不足,则显示省略号)。

并且所有 A、B、C、D 都应该左对齐前一个的右边缘。

有少数情况,但这四个涵盖了大部分情况。

1. Parent width is enough for all

|-|AAAA|B|CCCCCCCC|DDD|--------------|-|

2. C is too large and have to show ellipses


|-|AAAAA|B|CCCCCCCCCCCCC...|DDD|-|

  3. A is large and have to show ellipse for C to be able to show

|-|AAAAAAA..........|B|CCCCCCCC|DDD|-|



4. the parent width is not enough for showing A and C completely, so A and C both show ellipses


|-|AAAAAAAAAAAAAA...|B|CCCCC...|DDD|-|

所以规则是尽可能地显示 A,C 要么全部显示要么用省略号显示,以防显示 C 的 minWidth 仍然不能完整显示 A,然后用省略号显示 A。

试过LinearLayout、RelativeLayout和ConstraintLayout都没有得到想要的结果。

这对于 A 和 C 有两个 maxWidth,问题是如果 A 或 C 太小,另一个可能在不使用所有可用空间的情况下仍然显示省略号。

   <LinearLayout
        android:id="@+id/container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:orientation="horizontal"
        >


        <TextView
            android:id="@+id/a_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:maxWidth="130dp"
            android:maxLines="1"
            android:textSize="16sp"
            android:textStyle="bold"
            tools:text="ee" />

        <ImageView
            android:id="@+id/b_checked"
            android:layout_width="12dp"
            android:layout_height="12dp"
            android:layout_marginStart="3dp"
            android:layout_marginEnd="8dp"
            android:baselineAlignBottom="true"
            app:srcCompat="@drawable/checked" />

        <TextView
            android:id="@+id/c_id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:ellipsize="end"
            android:maxWidth="150dp"
            android:maxLines="1"
            tools:text="aasdasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa" />

        <TextView
            android:id="@+id/d_time"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_gravity="left"
            tools:text="30 Nov 18"
            />

    </LinearLayout>

如果在派生视图中执行此操作并覆盖 onMeasure(),则计算不会直接进行,并且 A、C 宽度可能不会立即可用。

如何只在布局xml中做到这一点,或者有可能吗?

【问题讨论】:

    标签: android android-layout


    【解决方案1】:

    我不确定这是否符合您的要求,但这是我尝试使用ConstraintLayout

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="16dp">
    
        <TextView
            android:id="@+id/one"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#eee"
            android:ellipsize="end"
            android:maxLines="1"
            android:text="something very very very very very long"
            app:layout_constraintHorizontal_bias="0"
            app:layout_constraintHorizontal_chainStyle="packed"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toLeftOf="@id/two"
            app:layout_constraintTop_toTopOf="parent"/>
    
        <TextView
            android:id="@+id/two"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="fixed"
            app:layout_constraintBaseline_toBaselineOf="@id/one"
            app:layout_constraintLeft_toRightOf="@id/one"
            app:layout_constraintRight_toLeftOf="@id/three"/>
    
        <TextView
            android:id="@+id/three"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="#eee"
            android:ellipsize="end"
            android:maxLines="1"
            android:text="this is pretty short"
            app:layout_constraintBaseline_toBaselineOf="@id/one"
            app:layout_constraintLeft_toRightOf="@id/two"
            app:layout_constraintRight_toLeftOf="@id/four"
            app:layout_constraintWidth_default="wrap"/>
    
        <TextView
            android:id="@+id/four"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="fixed"
            app:layout_constraintBaseline_toBaselineOf="@id/one"
            app:layout_constraintLeft_toRightOf="@id/three"
            app:layout_constraintRight_toRightOf="parent"/>
    
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    这里的重要部分是第一个“可拉伸”视图使用wrap_content,而第二个使用0dp 加上app:layout_constraintWidth_default="wrap"。这将使第一个视图的空间比第二个视图具有更高的优先级,但同时允许扩大和缩小。

    我发现的唯一问题是,当第一个视图的文本非常长时,它可以将其他视图推到彼此之上。这可以通过向第一个视图添加最大宽度来解决:

    app:layout_constraintWidth_max="256dp"
    

    一些截图:

    【讨论】:

    • 它似乎工作(需要maxWidth,这对于纵向和横向都很难选择)。其他帖子 (stackoverflow.com/a/56580441/2987953) 提到 layout_constraintWidth_default 已弃用,使用 layout_constrainedWidth=”true" 也是如此。
    • layout_constrainedWidth=”true" 行为与layout_constraintWidth_default="wrap" 不同,layout_constrainedWidth=true 将第四个视图推开,而不是在第三个视图的右侧流动。所以必须像 Ben 一样使用 layout_constraintWidth_default
    猜你喜欢
    • 1970-01-01
    • 2014-09-23
    • 1970-01-01
    • 2017-12-07
    • 1970-01-01
    • 1970-01-01
    • 2021-01-28
    • 1970-01-01
    • 2014-10-14
    相关资源
    最近更新 更多