在Android开发中,可能会遇到一个这样的问题:水平方向有多个控件,一般为左中右三个,需求一般要求最右边的需要动态跟随左边的宽度动态变化,如果左边的宽度太长,要求右边的抵拢右边界显示完整,左边的可以压缩打点显示或者滚动显示,示例图如下:
单纯的给中间设置权重layout_weight其实是不行的,百度谷歌了几个类似需求的文章,不尽人意,大家选择性参考
https://blog.csdn.net/weixin_43979538/article/details/115427010
https://juejin.cn/post/7234060427411849271
https://www.jianshu.com/p/1023b4c27b1b
- 不过上面第一个文章使用的约束布局的layout_constrainedWidth还是有用的,之前用到过,核心是:constrainedWidth、constraintHorizontal_bias、constraintHorizontal_chainStyle,具体代码如下:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/userNickNameT"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="1dp"
android:ellipsize="end"
android:singleLine="true"
android:text="加载中..."
android:textColor="#ff262628"
android:textSize="24dp"
android:textStyle="bold"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/sexImgV"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/sexImgV"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginEnd="8dp"
android:src="@drawable/icon_sex_man"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@id/userNickNameT"
app:layout_constraintRight_toLeftOf="@+id/vipFlagRy"
app:layout_constraintTop_toTopOf="parent" />
<com.cy.necessaryview.shapeview.RecShapeLinearLayout
android:id="@+id/vipFlagRy"
android:layout_width="63dp"
android:layout_height="22dp"
android:gravity="center"
android:orientation="horizontal"
android:visibility="gone"
app:colorFill="#1B888888"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@id/sexImgV"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:radiusCorner="12dp"
tools:visibility="visible">
<ImageView
android:id="@+id/vipFlagImgV"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/icon_vip_flag_normal" />
<TextView
android:id="@+id/vipFlagT"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="1dp"
android:text="SVIP"
android:textColor="#888888"
android:textSize="12dp" />
</com.cy.necessaryview.shapeview.RecShapeLinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
- 最后我采用的终极方案就是动态测量计算设置maxWidth,然后拿父级宽度来减去固定的左/右控件的宽度,这样就得到了中间控件的最大宽度,中间控件设置成wrap_content即可,代码如下:
<LinearLayout
android:id="@+id/topTitleLy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:orientation="horizontal">
<com.cy.necessaryview.shapeview.RecShapeTextView
android:id="@+id/textTag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:gravity="center"
android:maxEms="6"
android:maxLines="1"
android:paddingStart="3dp"
android:paddingTop="2dp"
android:paddingEnd="3dp"
android:paddingBottom="2dp"
android:text="亚服"
android:textColor="#33E6F6"
android:textSize="10dp"
app:colorFill="#1A33E6F6"
app:radiusCorner="4sp" />
<widget.RollTextView
android:id="@+id/textNameT"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="3dp"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:textColor="@color/color_FFFFFF"
android:textSize="14sp"
tools:text="测试数据测试数据" />
<TextView
android:id="@+id/videoFreeAccTag"
android:layout_width="93.25dp"
android:layout_height="20dp"
android:gravity="center"
android:visibility="gone"
android:background="@drawable/icon_free_video_acc_tag"
android:text="限时支持免费加速"
android:textColor="@color/color_white"
android:textSize="10dp"
tools:visibility="visible"/>
</LinearLayout>
//实现布局右优先加可变位置
topTitleLy.post {
calcSetTextNameMaxWidth(topTitleLy.width, textTag.width, videoFreeAccTag.width, textNameT)
}
textTag.post {
calcSetTextNameMaxWidth(topTitleLy.width, textTag.width, videoFreeAccTag.width, textNameT)
}
videoFreeAccTag.post {
calcSetTextNameMaxWidth(topTitleLy.width, textTag.width, videoFreeAccTag.width, textNameT)
}
private fun calcSetTextNameMaxWidth(topTitleLyW: Int, textTagW: Int, videoFreeAccTagW: Int, textNameT: TextView) {
XLog.d("==calcSetTextNameMaxWidth==>topTitleLyW:$topTitleLyW textTagW:$textTagW videoFreeAccTagW:$videoFreeAccTagW")
val textNameTMaxW = topTitleLyW - textTagW - videoFreeAccTagW - PyUIDisplayHelper.dp2px(context, 10)
textNameT.maxWidth = textNameTMaxW
}