在 LinearLayout 中对 ConstraintLayout 实施运行时约束

Enforcing Runtime Constraints for ConstraintLayout inside LinearLayout

我在使用运行时生成的 UI 时遇到了一些困难,它没有遵循约束。根据 Android 的其他答案和文档,我尝试了 ConstraintSet 以及其他一些方法。

我正在为自定义 class 扩展 ConstraintLayout,它在应用程序的功能中具有不可或缺的一部分。我从 Web 服务器提取数据,然后创建这些对象并将它们添加到 LinearLayoutLinearLayoutConstraintLayoutTextView 都显示了它们的正确大小;但是,TextView 彼此重叠并且拒绝遵守任何约束。

我可以通过布局编辑器手动创建我想做的副本,而且效果很好。

我当前的设置(this 扩展了 ConstraintLayout,text_nametext_pointsTextViews):

    this.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));

    this.addView(text_name);
    this.addView(text_points);

    ConstraintSet constraints = new ConstraintSet();

    constraints.clone(this);

    constraints.constrainHeight(text_points.getId(), WRAP_CONTENT);
    constraints.constrainWidth(text_points.getId(), WRAP_CONTENT);
    constraints.constrainHeight(text_name.getId(), WRAP_CONTENT);
    constraints.constrainWidth(text_name.getId(), WRAP_CONTENT);

    constraints.connect(text_name.getId(), LEFT, getId(), LEFT);
    constraints.connect(text_points.getId(), RIGHT, getId(), RIGHT);

    constraints.applyTo(this);

constrainWidthconstrainHeight 有效;当我摆脱它们或更改值时,它会产生影响。但是,任何 connect 业务都什么都不做。 TextView 的文本大小合适,但不遵守任何约束。我是否遗漏了使 .connect 正常工作的某些行?

澄清一下:我有 ScrollView -> LinearLayout -> ConstraintLayout -> TextViews。在编辑器中创建时,约束可以正常工作。当在运行时使用 ConstraintSetConstraintLayout 的实例化中创建时,连接的约束无效,但其他属性有效。

编辑:确认一下,这是添加到 LinearLayout (LOCS) 的行数、LinearLayout (LDIM) 的大小、ConstraintLayout (LOCDIM) 的大小以及 TextViews (TVDIM) 的大小的输出, TV2DIM):

09-03 14:19:18.664 D/LOCS: 2
09-03 14:19:18.665 D/LDIM: 1080 w
09-03 14:19:18.665 D/LDIM: 58 h
09-03 14:19:18.665 D/LOCDIM: 1080 w
09-03 14:19:18.666 D/LOCDIM: 29 h
09-03 14:19:18.667 D/TVDIM: 165 w
09-03 14:19:18.667 D/TVDIM: 29 h
09-03 14:19:18.668 D/TV2DIM: 29 w
09-03 14:19:18.668 D/TV2DIM: 29 h

看到这个答案,我认为您缺少 clone() 指令。

问题是,以编程方式,未正确分配视图 ID。我在尝试边距、宽度、高度、比例和旋转的不同组合时发现了这一点——这两个视图都应用了相同的更改。

解决方案是通过以某种方式生成 ID 来自行设置 ID。但是,不允许针对低 API 版本 (<17),View.generateViewId();因此,您必须使用包裹在它周围的那些不幸的丑陋块之一:

int view_id;

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
    view_id = View.generateViewId();
} else {
    view_id = new Random(System.currentTimeMillis()).nextInt();
}

view.setId(view_id);

从那时起,您可以使用 view_idview.getId() 来表示 ConstraintSet

对于要添加到 ConstraintLayoutView 的父级,您可以使用 ConstraintSet.PARENT_ID.