如果某些链接视图受限于另一个链接视图,则ConstraintLayout链不起作用

Sir*_*Lam 4 android android-layout android-constraintlayout constraint-layout-chains

我不确定它是否是ConstraintLayout的错误,所以我试着询问是否有人知道我犯了什么错误.

我有一个布局,我想在屏幕上均匀分布3个元素.如下所示: 3个链式视图

我在它们之间形成了水平链条,正如你所看到的,它们均匀分布并且工作良好.

现在我想在每个元素中放置一个图像和一个TextView,如下所示: 在此输入图像描述

所以这就是我尝试做的,以元素1为例:

        <ImageView
            android:id="@+id/image1"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:src="@drawable/image1"
            app:layout_constraintBottom_toBottomOf="@id/element_1"
            app:layout_constraintLeft_toLeftOf="@id/element_1"
            app:layout_constraintTop_toTopOf="@id/element_1"
            app:layout_constraintRight_toLeftOf="@+id/text1"
            app:layout_constraintHorizontal_chainStyle="packed"/>

        <TextView
            android:id="@+id/text1"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginLeft="2dp"
            android:text="@string/text1"
            app:layout_constraintBottom_toBottomOf="@id/element_1"
            app:layout_constraintLeft_toRightOf="@id/image1"
            app:layout_constraintRight_toRightOf="@id/element_1"
            app:layout_constraintTop_toTopOf="@id/element_1"
            app:layout_constraintHorizontal_chainStyle="packed"
            android:gravity="center_vertical"/>
Run Code Online (Sandbox Code Playgroud)

可悲的是,它似乎"打破"了3个元素的链条.3个元素现在不会水平扩散,但包裹到非常小的尺寸: 在此输入图像描述

如果我删除了ImageView和TextView之间的链,它可以正常工作.但后来我无法将ImageView和TextView置于元素中心.

有没有人遇到这样的事情?你是如何解决的?

现在,我知道我至少有两种方法可以解决这个问题:
(1)使用一个带有复合drawable的TextView,而不是ImageView + TextView;
(2)使用LinearLayout包装ImageView和TextView

但我想知道为什么它不起作用(这样我们可以更好地理解ConstraintLayout),而不是找到替代方案.

谢谢!

Che*_*amp 6

在发布了我对这个问题的另一个答案后,我意识到它没有解决如何集中多线TextView.

在此输入图像描述

参考上图,最左边的框有一行TextView.的TextViewImageView为中心作为盒子的基团.这是通过为以下内容指定以下内容来完成的TextView.

<TextView
    android:layout_width="0dp"
    app:layout_constraintWidth_default="wrap" 
    .. the rest of it .../>
Run Code Online (Sandbox Code Playgroud)

有关使用的信息,请参阅此帖子app:layout_constraintWidth_default="wrap".

app:layout_constraintWidth_default="wrap"(宽度设置为0dp).如果设置,小部件将具有与使用wrap_content相同的大小,但将受到约束的限制(即它不会扩展超出它们)

更新:看起来上面的XML需要针对ConstraintLayout1.1.0 beta2 进行更改.请参阅发布更新.

我认为我们现在在XML中寻找的是以下内容:

<TextView
    android:layout_width="wrap_content"
   app:layout_constrainedWidth="true"
    .. the rest of it .../>
Run Code Online (Sandbox Code Playgroud)

我使用1.1.0之前的Beta2布局离开了这篇文章的其余部分.要进行更新,只需进行上述更改即可.中心问题仍然存在.


这适用于单行示例,并且视图在框中居中,但是当TextView跨越多行时我们遇到困难,就像在上面的图像的中间框中一样.虽然内的文本TextView被包裹,并且不扩大超出其限制,ImageViewTextView没有像中心我们可以期待.实际上,TextView延伸到蓝框右边的界限.

我的快速解决方法是在最右边的框Space的左侧插入一个零宽度小部件ImageView.链是该框现在锚定在Space小部件和框的右侧之间.该ImageView约束由左边Space.

Space现在可以将窗口小部件扩展为像垫片一样ImageView向右移动将链中心的数量.(请参见上图中的右侧框.)计算窗口小部件需要的宽度的getExcessWidth()方法.MainActivitySpace

这是XML:

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:id="@+id/element_1"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="32dp"
        android:background="@color/colorPrimary"
        app:layout_constraintEnd_toStartOf="@+id/element_2"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/element_2"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="32dp"
        android:background="@color/colorPrimary"
        app:layout_constraintEnd_toStartOf="@+id/element_3"
        app:layout_constraintStart_toEndOf="@+id/element_1"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:id="@+id/element_3"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="32dp"
        android:background="@color/colorPrimary"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/element_2"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/image1"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:layout_marginLeft="8dp"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintBottom_toBottomOf="@id/element_1"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintLeft_toLeftOf="@id/element_1"
        app:layout_constraintRight_toLeftOf="@+id/text1"
        app:layout_constraintTop_toTopOf="@id/element_1" />

    <ImageView
        android:id="@+id/image2"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:layout_marginLeft="8dp"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintBottom_toBottomOf="@id/element_2"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintLeft_toLeftOf="@id/element_2"
        app:layout_constraintRight_toLeftOf="@+id/text2"
        app:layout_constraintTop_toTopOf="@id/element_2" />

    <android.support.v4.widget.Space
        android:id="@+id/spacer3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="@id/element_3"
        app:layout_constraintLeft_toLeftOf="@id/element_3"
        app:layout_constraintTop_toTopOf="@id/element_3" />

    <ImageView
        android:id="@+id/image3"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:layout_marginLeft="8dp"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintBottom_toBottomOf="@id/element_3"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintLeft_toRightOf="@id/spacer3"
        app:layout_constraintRight_toLeftOf="@id/text3"
        app:layout_constraintTop_toTopOf="@id/element_3" />

    <TextView
        android:id="@+id/text1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginLeft="2dp"
        android:layout_marginRight="8dp"
        android:gravity="center_vertical"
        android:text="String"
        android:textColor="@android:color/white"
        app:layout_constraintBottom_toBottomOf="@id/element_1"
        app:layout_constraintLeft_toRightOf="@id/image1"
        app:layout_constraintRight_toRightOf="@id/element_1"
        app:layout_constraintTop_toTopOf="@id/element_1"
        app:layout_constraintWidth_default="wrap" />

    <TextView
        android:id="@+id/text2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginLeft="2dp"
        android:layout_marginRight="8dp"
        android:gravity="center_vertical"
        android:text="A 2-line string"
        android:textColor="@android:color/white"
        app:layout_constraintBottom_toBottomOf="@id/element_2"
        app:layout_constraintLeft_toRightOf="@id/image2"
        app:layout_constraintRight_toRightOf="@id/element_2"
        app:layout_constraintTop_toTopOf="@id/element_2"
        app:layout_constraintWidth_default="wrap" />

    <TextView
        android:id="@+id/text3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginRight="8dp"
        android:gravity="center_vertical"
        android:text="A 2-line string"
        android:textColor="@android:color/white"
        app:layout_constraintBottom_toBottomOf="@id/element_3"
        app:layout_constraintLeft_toRightOf="@id/image3"
        app:layout_constraintRight_toRightOf="@id/element_3"
        app:layout_constraintTop_toTopOf="@id/element_3"
        app:layout_constraintWidth_default="wrap" />

</android.support.constraint.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.chained_chains);
        ConstraintLayout layout = (ConstraintLayout) findViewById(R.id.constraintLayout);

        layout.post(new Runnable() {
            @Override
            public void run() {
                final TextView textView = (TextView) findViewById(R.id.text3);
                int excessWidth = getExcessWidth(textView);

                if (excessWidth > 0) {
                    Space spacer = (Space) findViewById(R.id.spacer3);
                    ConstraintLayout.LayoutParams lp = (ConstraintLayout.LayoutParams) spacer.getLayoutParams();
                    lp.width = getExcessWidth(textView) / 2;
                    spacer.setLayoutParams(lp);
                }
            }
        });
    }

    private int getExcessWidth(TextView textView) {

        if (textView.getLineCount() <= 1) {
            return 0;
        }

        Layout layout = textView.getLayout();
        int maxWidth = 0;

        for (int i = 0; i < textView.getLineCount(); i++) {
            maxWidth = Math.max(maxWidth, (int) layout.getLineWidth(i));
        }

        return Math.max(textView.getWidth() - maxWidth, 0);
    }
}
Run Code Online (Sandbox Code Playgroud)