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

时间:2018-11-20 10:12:56

标签: android android-layout android-constraintlayout

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

//Pseudo code
textLayout = text + time 
usernameLayout = senderName

if(usernameLayout == gone){
    textLayout width == wrap_content
}else{
  textLayout minimum width == usernameLayout width  
}

输出像这样

With wrap_content

我想要的结果

With width==0dp

布局代码

<?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_text_layout的宽度0dp和tvUserName设置为一些文本,则它们起作用,但是如果tvUserName = gone,则它不起作用。

3 个答案:

答案 0 :(得分:0)

logical_or_layer(x)中删除以下行,因为视图只能在两个约束下使用。设置了ll_msg_inforight/end约束后,您的布局便可以使用该约束。

bottom

答案 1 :(得分:0)

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

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代码(用于名为“聊天”的可绘制对象):

<?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>

屏幕截图(上面的代码):

适用于屏幕尺寸-5.0英寸(1080 x 1920像素)[设备:像素]

enter image description here

您也可以针对不同的屏幕尺寸运行此命令,对我来说绝对可以。

希望对您有所帮助。

答案 2 :(得分:0)

经过反复试验后,此解决方案有效

感谢Sinan Ergin stackoverflow答案。

enter image description here

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());
    }
  }
}

attrs.xml

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