草庐IT

android - 如果某些链接 View 约束到另一个链接 View ,则 ConstraintLayout 链不起作用

coder 2023-12-20 原文

我不确定这是否是 ConstraintLayout 的错误,所以我想问问是否有人知道我犯了什么错误。

我有一个布局,我想在屏幕上均匀分布 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"/>

可悲的是,它似乎“打破”了 3 元素的链条。这 3 个元素现在不再水平展开,而是包裹成一个非常小的尺寸:

如果我删除了 ImageView 和 TextView 之间的链,它就可以正常工作。但是我无法在元素内将 ImageView 和 TextView 居中。

有没有人遇到过这样的事情?你是怎么解决的?

现在,我知道我至少有 2 个替代方案来解决这个问题:
(1) 使用一个带有复合可绘制对象的 TextView,而不是 ImageView + TextView;
(2) 用一个LinearLayout 包裹ImageView 和TextView

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

谢谢!

最佳答案

在发布我对这个问题的其他答案后,我意识到它没有解决如何使多行居中 TextView 的问题。 .

引用上图,最左边的框有一行TextView . TextViewImageView在框中作为一个组居中。这是通过为 TextView 指定以下内容来完成的.

<TextView
    android:layout_width="0dp"
    app:layout_constraintWidth_default="wrap" 
    .. the rest of it .../>

参见 this posting关于 app:layout_constraintWidth_default="wrap" 的使用.

app:layout_constraintWidth_default="wrap" (with width set to 0dp). If set, the widget will have the same size as if using wrap_content, but will be limited by constraints (i.e. it won't expand beyond them)

更新: 上面的 XML 看起来需要针对 ConstraintLayout 进行更改1.1.0 测试版 2。查看release update .

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

<TextView
    android:layout_width="wrap_content"
   app:layout_constrainedWidth="true"
    .. the rest of it .../>

我使用 1.1.0 之前的 beta2 布局保留了这篇文章的其余部分。要更新,只需进行上述更改即可。居中问题仍然存在。


这对于单行示例非常有效并且 View 在框中居中,但是当 TextView 时我们遇到了困难跨越多行,就像在上图的中间框中一样。虽然TextView内的文字被包裹并且不会超出其约束,ImageViewTextView不像我们预期的那样居中。事实上,TextView 的范围延伸到蓝色框的右侧。

我的快速解决方法是插入一个零宽度的 Space ImageView 左侧的小部件在最右边的框中。链条是那个盒子现在锚定在 Space 之间。小部件和框的右侧。 ImageViewSpace 限制在左侧.

Space现在可以扩展小部件以充当垫片来移动 ImageView向右移动将使链居中的量。 (见上图中的右方框。)getExcessWidth() MainActivity的方法|计算 Space 的宽度小部件需要。

这是 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>

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

关于android - 如果某些链接 View 约束到另一个链接 View ,则 ConstraintLayout 链不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46537109/

有关android - 如果某些链接 View 约束到另一个链接 View ,则 ConstraintLayout 链不起作用的更多相关文章

  1. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  2. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  3. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  4. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  5. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  6. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

  7. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  8. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  9. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  10. ruby-on-rails - Rails - 从另一个模型中创建一个模型的实例 - 2

    我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案

随机推荐