Android 如何从xml中将约束布局最小宽度设置为另一个视图的宽度

Android 如何从xml中将约束布局最小宽度设置为另一个视图的宽度,android,android-layout,android-constraintlayout,Android,Android Layout,Android Constraintlayout,在组消息集的消息行中,最小(文本和时间)布局宽度是用户名视图的宽度。见下图(见时间对齐) 输出是这样的 下面是我想要的结果 布局代码 <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.an

在组消息集的消息行中,最小(文本和时间)布局宽度是用户名视图的宽度。见下图(见时间对齐)

输出是这样的

下面是我想要的结果

布局代码

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/message_row_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|bottom"
android:baselineAligned="false"
android:paddingStart="@dimen/padding_8dp"
android:paddingEnd="40dp">


<android.support.constraint.ConstraintLayout
    android:id="@+id/message_box"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/chat_incoming_bg">

    <TextView
        android:id="@+id/tvUserName"
        style="@style/TextStyle.Chat.Item.Name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="4dp"
        android:layout_marginEnd="8dp"
        android:ellipsize="end"
        android:fontFamily="sans-serif-medium"
        android:maxLines="1"
        android:paddingEnd="@dimen/padding_8dp"
        android:text="Jarvis Pixel9 New testName "
        android:textColor="@color/red800"
        android:visibility="visible"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <android.support.constraint.ConstraintLayout
        android:id="@+id/chat_text_layout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="start"
        android:gravity="start"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tvUserName">


        <com.vanniktech.emoji.EmojiTextView
            android:id="@+id/message_body"
            style="@style/Base.TextAppearance.AppCompat.Body1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="@dimen/padding_8dp"
            android:paddingTop="@dimen/padding_4dp"
            android:paddingRight="@dimen/padding_8dp"
            android:paddingBottom="@dimen/padding_8dp"
            android:text="Hijkhkfjhds"
            android:textColorLink="@color/link_color"
            android:textSize="?attr/TextSizeBody"
            app:emojiSize="28sp"
            tools:ignore="MissingConstraints"
            tools:layout_editor_absoluteY="0dp" />

        <LinearLayout
            android:id="@+id/ll_msg_info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end|bottom"
            android:gravity="end|bottom"
            android:minWidth="60dp"
            android:orientation="horizontal"
            android:paddingEnd="@dimen/padding_8dp"
            android:paddingBottom="@dimen/padding_4dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="1.0"
            app:layout_constraintStart_toEndOf="@+id/message_body"
            tools:ignore="RtlSymmetry">

            <TextView
                android:id="@+id/message_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:gravity="center_vertical"
                android:text="12:50 PM"
                android:textColor="@color/black54"
                android:textSize="?attr/TextSizeInfo" />

            <ImageView
                android:id="@+id/img_failed_status"
                android:layout_width="16dp"
                android:layout_height="16dp"
                android:layout_gravity="center_vertical"
                android:layout_marginStart="4dp"
                android:gravity="center_vertical"
                android:src="@drawable/ic_cancel_24dp"
                android:visibility="gone" />
        </LinearLayout>

    </android.support.constraint.ConstraintLayout>

    </android.support.constraint.ConstraintLayout>

    </android.support.constraint.ConstraintLayout>


如果我设置了
chat\u text\u布局
width 0dp和
tvUserName
,但如果
tvUserName=gone
则不起作用。

ll\u msg\u info
中删除以下行,因为视图只能使用两个约束条件。由于您已经设置了
右/端
底部
约束,您的布局将使用这些约束

app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@+id/message_body"

我认为,下面的代码将满足您的用例

XML代码(用于布局):

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/chat">

    <TextView
        android:id="@+id/tvName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxWidth="300dp"
        android:text="This Is A Very Long Name As You See"
        android:paddingStart="20dp"
        android:paddingEnd="4dp"
        android:textSize="16sp"
        android:textColor="@android:color/holo_red_dark"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tvComment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxWidth="300dp"
        android:text="This is some comment."
        android:paddingStart="20dp"
        android:paddingEnd="4dp"
        android:textSize="18sp"
        android:textColor="@android:color/black"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tvName" />

    <TextView
        android:id="@+id/tvTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="12:50"
        android:textSize="14sp"
        android:paddingEnd="5dp"
        android:paddingBottom="3dp"
        app:layout_constraintTop_toBottomOf="@+id/tvComment"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="1.0" />
</android.support.constraint.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <rotate
            android:fromDegrees="-45"
            android:pivotX="0%"
            android:pivotY="0%"
            android:toDegrees="0" >
            <shape android:shape="rectangle" >
                <solid android:color="@android:color/holo_green_light" />
            </shape>
        </rotate>
    </item>

    <item android:left="16dp">
        <shape android:shape="rectangle" >
            <solid android:color="@android:color/holo_green_light" />
            <corners android:radius="6dp" />
        </shape>
    </item>
</layer-list>

你也可以在不同的屏幕尺寸下运行这个,对我来说非常好


我希望,这对您有所帮助。

经过大量的尝试和错误,这个解决方案正在发挥作用

谢谢你的回答

XML布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/message_row_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|bottom"
android:baselineAligned="false"
android:paddingStart="@dimen/padding_8dp"
android:paddingEnd="40dp">

<android.support.constraint.ConstraintLayout
    android:id="@+id/message_box"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginEnd="8dp"
    android:background="@drawable/chat_incoming_bg"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">
    <!--User Name -->
    <android.support.constraint.ConstraintLayout
        android:id="@+id/user_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/tvContactName"
            style="@style/TextStyle.Chat.Item.Name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginTop="4dp"
            android:layout_marginEnd="8dp"
            android:ellipsize="end"
            android:fontFamily="sans-serif-medium"
            android:paddingEnd="@dimen/padding_8dp"
            android:textColor="@color/red800"
            android:visibility="visible"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/tvServerName"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />


        <TextView
            android:id="@+id/tvServerName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginTop="4dp"
            android:layout_marginEnd="4dp"
            android:ellipsize="end"
            android:maxEms="7"
            android:maxLength="20"
            android:maxLines="1"
            android:scrollHorizontally="true"
            android:singleLine="true"
            android:textSize="12sp"
            android:visibility="visible"
            app:layout_constraintBaseline_toBaselineOf="@+id/tvContactName"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="1.0"
            app:layout_constraintStart_toEndOf="@+id/tvContactName"
            app:layout_constraintTop_toTopOf="parent" />

    </android.support.constraint.ConstraintLayout>
    <!--Message Layout-->
    <com.shain.views.ChatTextLayout
        android:id="@+id/qt_chat_text_layout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/user_layout"
        app:layout_constraintVertical_bias="0.50"
        app:layout_constraintWidth_min="wrap"
        app:viewPartMain="@+id/message_body"
        app:viewPartSlave="@+id/ll_msg_info">


        <com.vanniktech.emoji.EmojiTextView
            android:id="@+id/message_body"
            style="@style/Base.TextAppearance.AppCompat.Body1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:focusableInTouchMode="false"
            android:paddingLeft="@dimen/padding_8dp"
            android:paddingTop="@dimen/padding_4dp"
            android:paddingBottom="@dimen/padding_4dp"
            android:paddingRight="@dimen/padding_8dp"
            android:textColorLink="@color/link_color"
            android:textSize="?attr/TextSizeBody"
            app:emojiSize="28sp"
            tools:ignore="MissingConstraints" />

        <LinearLayout
            android:id="@+id/ll_msg_info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end|bottom"
            android:gravity="end|bottom"
            android:minWidth="60dp"
            android:orientation="horizontal"
            android:paddingEnd="@dimen/padding_8dp"
            android:paddingBottom="@dimen/padding_4dp"
            tools:ignore="RtlSymmetry">

            <TextView
                android:id="@+id/message_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:gravity="center_vertical"
                android:textColor="@color/black54"
                android:textSize="?attr/TextSizeInfo" />

            <ImageView
                android:id="@+id/img_failed_status"
                android:layout_width="16dp"
                android:layout_height="16dp"
                android:layout_gravity="bottom"
                android:layout_marginStart="4dp"
                android:gravity="center_vertical"
                android:src="@drawable/ic_cancel_24dp"
                android:visibility="gone" />
        </LinearLayout>

    </com.shain.views.ChatTextLayout>

</android.support.constraint.ConstraintLayout>

Java自定义视图代码

public class ChatTextLayout extends ConstraintLayout {

private int widthSize;
private int heightSize;

private TextView viewPartMain;
private View viewPartSlave;
private TypedArray a;

private LayoutParams viewPartMainLayoutParams;
private int viewPartMainWidth;
private int viewPartMainHeight;

private LayoutParams viewPartSlaveLayoutParams;
private int viewPartSlaveWidth;
private int viewPartSlaveHeight;

private boolean withGroupHeader = false;

public ChatTextLayout(Context context) {
    super(context);
}

public ChatTextLayout(Context context, AttributeSet attrs) {
    super(context, attrs);

    a = context.obtainStyledAttributes(attrs, R.styleable.MessageTextStyle, 0, 0);
}

public void setWithGroupHeader(boolean withGroupHeader) {
    this.withGroupHeader = withGroupHeader;
}

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();

    try {
        viewPartMain = this.findViewById(a.getResourceId(R.styleable.MessageTextStyle_viewPartMain, -1));
        viewPartSlave = this.findViewById(a.getResourceId(R.styleable.MessageTextStyle_viewPartSlave, -1));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    widthSize = MeasureSpec.getSize(widthMeasureSpec);
    heightSize = MeasureSpec.getSize(heightMeasureSpec);

    if (viewPartMain == null || viewPartSlave == null || widthSize <= 0) {
        return;
    }

    int availableWidth = widthSize - getPaddingLeft() - getPaddingRight();
    int availableHeight = heightSize - getPaddingTop() - getPaddingBottom();

    viewPartMainLayoutParams = (LayoutParams) viewPartMain.getLayoutParams();
    viewPartMainWidth = viewPartMain.getMeasuredWidth() + viewPartMainLayoutParams.leftMargin + viewPartMainLayoutParams.rightMargin;
    viewPartMainHeight = viewPartMain.getMeasuredHeight() + viewPartMainLayoutParams.topMargin + viewPartMainLayoutParams.bottomMargin;

    viewPartSlaveLayoutParams = (LayoutParams) viewPartSlave.getLayoutParams();
    viewPartSlaveWidth = viewPartSlave.getMeasuredWidth() + viewPartSlaveLayoutParams.leftMargin + viewPartSlaveLayoutParams.rightMargin;
    viewPartSlaveHeight = viewPartSlave.getMeasuredHeight() + viewPartSlaveLayoutParams.topMargin + viewPartSlaveLayoutParams.bottomMargin;

    int viewPartMainLineCount = viewPartMain.getLineCount();
    float viewPartMainLastLineWidth = viewPartMainLineCount > 0 ? viewPartMain.getLayout().getLineWidth(viewPartMainLineCount - 1) : 0;

    widthSize = getPaddingLeft() + getPaddingRight();
    heightSize = getPaddingTop() + getPaddingBottom();

    if (viewPartMainLineCount > 1 && !(viewPartMainLastLineWidth + viewPartSlaveWidth > viewPartMain.getMeasuredWidth())) {
        widthSize += viewPartMainWidth;
        heightSize += viewPartMainHeight;
    } else if (viewPartMainLineCount > 1 && (viewPartMainLastLineWidth + viewPartSlaveWidth > availableWidth)) {
        widthSize += viewPartMainWidth;
        heightSize += viewPartMainHeight + viewPartSlaveHeight;
    } else if (viewPartMainLineCount == 1 && (viewPartMainWidth + viewPartSlaveWidth > availableWidth)) {
        widthSize += viewPartMain.getMeasuredWidth();
        heightSize += viewPartMainHeight + viewPartSlaveHeight;
    } else {
        heightSize += viewPartMainHeight;
        widthSize += viewPartMainWidth + viewPartSlaveWidth;
    }

    this.setMeasuredDimension(widthSize, heightSize);
    super.onMeasure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY));

}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);

    if (viewPartMain == null || viewPartSlave == null) {
        return;
    }
    if (withGroupHeader) {
        viewPartMain.layout(
                getPaddingLeft(),
                getPaddingTop() - Utils.dp(4f),
                viewPartMain.getWidth() + getPaddingLeft(),
                viewPartMain.getHeight() + getPaddingTop());

        viewPartSlave.layout(
                right - left - viewPartSlaveWidth - getPaddingRight(),
                bottom - top - getPaddingBottom() - viewPartSlaveHeight,
                right - left - getPaddingRight(),
                bottom - top - getPaddingBottom());
    } else {
        viewPartMain.layout(
                getPaddingLeft(),
                getPaddingTop(),
                viewPartMain.getWidth() + getPaddingLeft(),
                viewPartMain.getHeight() + getPaddingTop());

        viewPartSlave.layout(
                right - left - viewPartSlaveWidth - getPaddingRight(),
                bottom - top - getPaddingBottom() - viewPartSlaveHeight,
                right - left - getPaddingRight(),
                bottom - top - getPaddingBottom());
    }
  }
}
public类chatterxtlayout扩展了ConstraintLayout{
私有整数大小;
私人内部高度尺寸;
私有文本视图viewPartMain;
私用视图部件从机;
私有类型Darray a;
私有布局参数viewPartMainLayoutParams;
私有int viewPartMainWidth;
私有内部视图部件主高度;
专用布局参数ViewPartsSlavelayOutParams;
私有int viewPartSlaveWidth;
私有内部视图部件slavehight;
私有布尔值withGroupHeader=false;
公共布局(上下文){
超级(上下文);
}
公共chatterxtlayout(上下文、属性集属性){
超级(上下文,attrs);
a=context.actainStyledAttributes(attrs,R.styleable.MessageTextStyle,0,0);
}
public void setWithGroupHeader(布尔withGroupHeader){
this.withGroupHeader=withGroupHeader;
}
@凌驾
受保护的无效数据附加到DOWINDOW(){
super.onAttachedToWindow();
试一试{
viewPartMain=this.findViewById(a.getResourceId(R.styleable.MessageTextStyle_viewPartMain,-1));
viewPartSlave=this.findViewById(a.getResourceId(R.styleable.MessageTextStyle_viewPartSlave,-1));
}捕获(例外e){
e、 printStackTrace();
}
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
超级测量(宽度测量、高度测量);
widthSize=MeasureSpec.getSize(widthMeasureSpec);
heightSize=MeasureSpec.getSize(heightMeasureSpec);
如果(viewPartMain==null | | viewPartSlave==null | | |宽度大小0?viewPartMain.getLayout().getLineWidth(viewPartMainLineCount-1):0;
宽度大小=getPaddingLeft()+getPaddingRight();
heightSize=getPaddingTop()+getPaddingBottom();
如果(viewPartMainLineCount>1&!(viewPartMainLastLineWidth+viewPartSlaveWidth>viewPartMain.getMeasuredWidth()){
宽度大小+=viewPartMainWidth;
heightSize+=viewPartMainHeight;
}否则如果(viewPartMainLineCount>1&(viewPartMainLastLineWidth+viewPartSlaveWidth>availableWidth)){
宽度大小+=viewPartMainWidth;
heightSize+=viewPartMainHeight+viewPartSlaveHeight;
}否则如果(viewPartMainLineCount==1&&(viewPartMainWidth+viewPartSlaveWidth>availableWidth)){
widthSize+=viewPartMain.getMeasuredWidth();
heightSize+=viewPartMainHeight+viewPartSlaveHeight;
}否则{
heightSize+=viewPartMainHeight;
宽度大小+=viewPartMainWidth+viewPartSlaveWidth;
}
此.设置测量尺寸(宽度尺寸、高度尺寸);
super.onMeasure(measpect.makemeaspect(widthSize,measpect.justice),measpect.makemeaspect(heightSize,measpect.justice));
}
@凌驾
仅限受保护的空心布局(布尔值已更改、整数左侧、整数顶部、整数右侧、整数底部){
超级。仅限布局(已更改、左、上、右、下);
如果(viewPartMain==null | | viewPartSlave==null){
返回;
}
if(带组头){
viewPartMain.layout(
getPaddingLeft(),
getPaddingTop()-Utils.dp(4f),
viewPartMain.getWidth()+getPaddingLeft(),
getHeight()+getPaddingTop());
viewPartSlave.layout(
右-左-viewPartSlaveWidth-getPaddingRight(),
底部-顶部-getPaddingBottom()-viewPartSlaveHeight,
右-左-getPaddingRight(),
底部-顶部-getPaddingBottom());
}否则{
viewPartMain.layout(
getPaddingLeft(),
getPaddingTop(),
viewPartMain.getWidth()+getPaddingLeft(),
getHeight()+getPaddingTop());
viewPartSlave.layout(
右-左-viewPartSlaveWidth-getPaddingRight(),
底部-顶部-getPaddingBottom()-viewPartSlaveHeight,
右-左-getPaddingRight(),
底部-顶部-getPaddingBottom());
}
}
}
attrs.xml

 <declare-styleable name="MessageTextStyle">
    <attr name="viewPartMain" format="reference"></attr>
    <attr name="viewPartSlave" format="reference"></attr>
</declare-styleable>


我希望我的回答已经解决了您的问题,如果您需要进一步的帮助,可以询问。:)您好,我检查过了,仍然不是很完美。它有更多的空格,气泡看起来很大。我正在开发类似Whatsapp的东西,时间布局会根据文本大小进行调整。我已经用新应用解决了上述问题:layout_constraintWidth_min=“wrap”在Constant layout 1.1.3中,但在较大的文本时间和文本布局重叠中,在上述代码中,时间文本视图将根据文本的长度(即名称文本和注释文本)进行调整,如果您仔细注意的话。此外,气泡大小也可以按照
 <declare-styleable name="MessageTextStyle">
    <attr name="viewPartMain" format="reference"></attr>
    <attr name="viewPartSlave" format="reference"></attr>
</declare-styleable>