【问题标题】:Android Constraint Layout Programmatically?以编程方式进行Android约束布局?
【发布时间】:2017-01-10 19:40:06
【问题描述】:

在 iOS 中,我非常喜欢删除情节提要并使用制图框架将所有内容放在代码中。这是从 Cartography 的 github 上偷来的:

constrain(view1, view2) { view1, view2 in
    view1.width   == (view1.superview!.width - 50) * 0.5
    view2.width   == view1.width - 50
    view1.height  == 40
    view2.height  == view1.height
    view1.centerX == view1.superview!.centerX
    view2.centerX == view1.centerX

    view1.top >= view1.superview!.top + 20
    view2.top == view1.bottom + 20
}

Android 是否有任何等价物?似乎新的约束布局是朝着正确方向迈出的一步,但我想以编程方式进行。

【问题讨论】:

  • 人们想要以编程方式执行此操作的原因有很多,例如,人们正在开发具有预定义用户界面的应用程序以外的库,或者人们需要更改受用户交互影响的布局规范在运行时甚至更多原因......谷歌真的缺乏这个新功能的文档
  • 另一个(简单)原因,@Polarbear0106 是,如果您需要使用 TransitionManager,尤其是 TransitionManager.beginDelayedTransition(root);,那么您需要手动指定您的布局更改,以便它们被渲染在下一关。所以,是的,有时您需要以编程方式修改内容。

标签: android android-layout


【解决方案1】:

游戏有点晚了,但您需要将约束布局中的视图基本上视为具有自己的 LayoutParams 的常规视图。

在 ConstraintLayout 情况下,文档位于此处:https://developer.android.com/reference/androidx/constraintlayout/widget/ConstraintLayout.LayoutParams

该类包含不同的属性,指定视图在 ConstraintLayout 中的布局方式。为了在运行时建立约束,建议使用 ConstraintSet。

所以,推荐的方法是使用ConstraintSet

那里有一个很好的代码示例,但核心概念是您需要创建一个新集合(通过复制/克隆/新建等),设置其属性,然后将其应用到您的布局中。

例如:假设您的布局包含一个 ConstraintLayout(此处称为 mConstraintLayout)并且其中包含一个视图(示例中为 R.id.go_button),您可以这样做:

    ConstraintSet set = new ConstraintSet();

    // You may want (optional) to start with the existing constraint,
    // so uncomment this.
    // set.clone(mConstraintLayout); 

    // Resize to 100dp
    set.constrainHeight(R.id.go_button, (int)(100 * density));
    set.constrainWidth(R.id.go_button, (int)(100 * density));

    // center horizontally in the container
    set.centerHorizontally(R.id.go_button, R.id.rootLayout);

    // pin to the bottom of the container
    set.connect(R.id.go_button, BOTTOM, R.id.rootLayout, BOTTOM, 8);

    // Apply the changes
    set.applyTo(mConstraintLayout); 
    // this is my… (ConstraintLayout) findViewById(R.id.rootLayout);

【讨论】:

  • 在我的情况下,必须添加 set.clone(mConstraintLayout) 以在添加之前复制当前约束
  • 你戴着拖把头吗@Martin Marconcini?
  • @TomHoward 我不敢! ;)(如果你好奇,thinkgeek.com/product/f0d0)如果链接在未来失败,谷歌“矮人胡须帽”(我带来它@think geek)就像 5 年前一样。
  • @CarlosPerezPerez 感谢您的评论,我认为这很清楚(在文本中),但为了更加清楚,我已经在此处添加了克隆代码(已注释掉)。 +1 :)
  • For building up constraints at run time, using ConstraintSet is recommended. 这句话让我很困惑。我以编程方式创建视图这一事实意味着我正在定义运行时的约束。所以我不明白那条线。我在stackoverflow.com/questions/60030308/… 有类似的问题。你能看看吗?
【解决方案2】:

我在 iOS 中遇到了完全相同的困境,我觉得以编程方式构建视图是一种更常见的做法。

我实际上正在使用 Kotlin hereStevia 库移植到 android,因为新的 ConstraintLayout 与我们心爱的 Autolayout 非常相似。

这是定义简单视图的方式

class MyView(context: Context): ConstraintLayout(context) {

  val label = TextView(context)

  init {

      // View Hierarchy
      subviews(
          label
      )

      // Layout
      label.centerInParent()

      // Style
      label.style {
          textSize = 12F
      }
  }}

请注意,这是引擎盖下的纯原生约束布局,正如 Martin 的回答所解释的那样。

这只是一个开始,但到目前为止,它已被证明是在 Kotlin 中编写 android 视图的一种令人愉快的方式,所以我想我会分享。 希望这会有所帮助:)

【讨论】:

  • 我是 iOS 上 Stevia 的用户和贡献者。这可能是最好的镜头。
猜你喜欢
  • 1970-01-01
  • 2012-10-01
  • 2018-04-08
  • 1970-01-01
  • 2019-06-01
  • 2021-11-22
  • 1970-01-01
  • 2021-12-22
  • 2020-05-31
相关资源
最近更新 更多