jetpack_在JetPack Compose中探索约束布局

jetpack

介绍 (Introduction)

These days JetPack-compose is evolving rapidly; one of the significant developments I’ve observed recently is constraint-layout in compose. Constraint layout is a compelling component, even in our traditional UI design (XML). So I thought of giving it a try to use in compose.

如今,JetPack-composeSwift发展。 我最近观察到的重要发展之一是compose中的约束布局。 约束布局是一个引人注目的组件,即使在我们的传统UI设计(XML)中也是如此。 所以我想尝试一下在组合中使用。

Constraint layout brought many advanced and powerful features to design UI. For starters, it’s a combination of traditional RelativeLayout and LinearLayout. We can also design a responsive layout with guidelines, barriers, chains and more.

约束布局为UI设计带来了许多先进而强大的功能。 首先,它是传统的RelativeLayoutLinearLayout的结合。 我们还可以设计包含指南,障碍,链条等的响应式布局。

The way constraint layout works in compose is similar to use it in the classic Android traditional view system. In compose, a ConstraintLayout requires a ConstraintSet as an argument. In which we’ve to place all the constraints of the layout. Children block contains the child’s of the layout.

约束布局在compose中的工作方式与在经典的Android传统视图系统中使用约束的方式类似。 在撰写过程中,ConstraintLayout需要使用ConstraintSet作为参数。 我们必须在其中放置布局的所有约束。 块包含布局的子元素。

要记住的事情 (Things to Remember)

约束集 (ConstraintSet)

As compose is an entirely different approach to design UI, likewise using constraint layout. As I said, we need to use constraintSet argument to mention all the constraints in the layout using tags.

作为compose是一种完全不同的设计UI的方法,同样使用约束布局。 就像我说的,我们需要使用constraintSet参数来使用标签提及布局中的所有约束。

标签 (Tag)

Tag is similar to id in the traditional view system. We need to mention all the children with unique tags so that we can reference them from constraintSet to declare alignments.

标签类似于传统视图系统中的id。 我们需要用唯一的标签提及所有子项,以便我们可以从constraintSet引用它们以声明对齐方式。

基本对齐 (Basic Alignments)

Let’s start with basic things — aligning views with regard to the Parent. By default, there are nine different alignments we can set to a child inside the constraint layout. These are the basic constraints used to align the child of the layout regarding the Parent.

让我们从基本的事情开始-使关于父项的观点保持一致。 默认情况下,可以在约束布局内为子级设置九种不同的路线。 这些是用于使布局的子项与父项对齐的基本约束。

To demonstrate the use of basic constraints, consider the black square as the container and the blue square inside it as a child. Please have a look at the below image on how we use basic constraints in compose.

为了演示基本约束的使用,请将黑色正方形视为容器,将其内部的蓝色正方形视为子级。 请看下图,了解我们如何在撰写中使用基本约束。

Image for post
basic constraints usage
基本约束用法

视图之间的对齐 (Alignment between Views)

Now that we know how to use primary constraints, let’s see how to set constraints if we have multiple views. Let’s take a simple example of TextView A at the center of the screen and TextViews B, C, D and E at left, right, top & bottom, respectively. To be clear, have a look at the output:

现在,我们知道了如何使用主要约束,让我们看看如果有多个视图,如何设置约束。 让我们以一个简单的示例为例,TextView A位于屏幕中心,TextViews B,C,D和E分别位于屏幕的左侧,右侧,顶部和底部。 要清楚,请看一下输出:

Image for post
target output
目标输出

Now, let’s see the implementation part where we have two sections

现在,让我们看一下实现部分,其中有两个部分

  1. ConstraintSet, where we mention all the constraints of the children.

    ConstraintSet ,其中提到了所有子代约束。

  2. Children block where we declare the children.

    儿童遮挡我们声明儿童的位置。
ConstraintLayout(constraintSet = ConstraintSet {
    
    // This block contains all the constraints related to children
    tag("TextViewA").apply {
        right constrainTo parent.right
        left constrainTo parent.left
        top constrainTo parent.top
        bottom constrainTo parent.bottom
    }
    tag("TextViewB").apply {
        right constrainTo tag("TextViewA").left
        top constrainTo tag("TextViewA").top
    }
    tag("TextViewC").apply {
        left constrainTo tag("TextViewA").right
        top constrainTo tag("TextViewA").top
    }
    tag("TextViewD").apply {
        right constrainTo parent.right
        left constrainTo parent.left
        bottom constrainTo tag("TextViewA").top
    }
    tag("TextViewE").apply {
        right constrainTo parent.right
        left constrainTo parent.left
        top constrainTo tag("TextViewA").bottom
    }
    
},modifier = Modifier.fillMaxSize()) {
    
    // This block contains the children
    Text(text = "A", modifier = Modifier.tag("TextViewA")
        .padding(10.dp),
        style = TextStyle(fontSize = 20.sp))
    Text(text = "B", modifier = Modifier.tag("TextViewB")
        .padding(10.dp)
        , style = TextStyle(fontSize = 20.sp))
    Text(text = "C", modifier = Modifier.tag("TextViewC")
        .padding(10.dp)
        , style = TextStyle(fontSize = 20.sp))
    Text(text = "D", modifier = Modifier.tag("TextViewD")
        , style = TextStyle(fontSize = 20.sp))
    Text(text = "E", modifier = Modifier.tag("TextViewE")
        , style = TextStyle(fontSize = 20.sp))
    
}

指导方针 (Guideline)

A guideline is an invisible view through which we can constraint the composables. The guideline can be aligned using percentage, offset and padding. As guidelines are invisible, we can create responsive UI using them.

准则是一种不可见的视图,通过它我们可以约束可组合物。 可以使用百分比,偏移量和填充来对齐准则。 由于准则不可见,因此我们可以使用准则来创建响应式用户界面。

To explore the usage of guidelines, let’s create a guideline aligning at the center of the screen. Then constraint View A and B on top & bottom of it. Have a look:

要探索准则的用法,我们创建一个在屏幕中央对齐的准则。 然后将视图A和B约束在其顶部和底部。 看一看:

ConstraintLayout(constraintSet = ConstraintSet {
    val half = createGuidelineFromTop(0.5f)
    tag("TextViewA").apply {
        top constrainTo half
        left constrainTo parent.left
        right constrainTo parent.right
    }
    tag("TextViewB").apply {
        bottom constrainTo half
        left constrainTo parent.left
        right constrainTo parent.right
    }
}, modifier = Modifier.fillMaxSize()) {
    Text(text = "A", modifier = Modifier.tag("TextViewA")
        .padding(10.dp),
        style = TextStyle(fontSize = 20.sp))
    Text(text = "B", modifier = Modifier.tag("TextViewB")
        .padding(10.dp)
        , style = TextStyle(fontSize = 20.sp))
}

Here createGuidelineFromTop to creates a guideline at a height percentage from the top. We used general constraints to align respective views at the top and bottom of the guideline.

在这里, createGuidelineFromTop可以在距顶部的高度百分比处创建一条createGuidelineFromTop 。 我们使用一般约束在指南的顶部和底部对齐各个视图。

Here we have a few more guideline functions similar createGuidelineFromTop, have a look:

在这里,我们还有一些类似于createGuidelineFromTop准则功能,看看:

  • createGuidelineFromTop: Creates a guideline at a specific offset/percentage from the top of the [ConstraintLayout].

    createGuidelineFromTop: 在距[ConstraintLayout]顶部特定偏移量/百分比处创建准则。

  • createGuidelineFromRight: Creates a guideline at a width offset/percentage from the right of the [ConstraintLayout].

    createGuidelineFromRight: 以[ConstraintLayout]右侧的宽度偏移/百分比创建一个 辅助线

  • createGuidelineFromLeft: Creates a guideline at a width offset/percentage from the left of the [ConstraintLayout].

    createGuidelineFromLeft: 以[ConstraintLayout]左侧的宽度偏移/百分比创建准则。

  • createGuidelineFromBottom: Creates a guideline at a specific offset/percentage from the bottom of the [ConstraintLayout].

    createGuidelineFromBottom: 在距[ConstraintLayout]底部特定偏移量/百分比处创建准则。

屏障 (Barrier)

A Barrier is a virtual view, similar to a Guideline. The barrier has reference to the views that you wish to use to form a “barrier” against. If anyone of the views grows, the barrier will adjust its size to the largest height or width of the referenced items.

Barrier是一个虚拟视图,类似于Guidelinebarrier参考了您希望用来形成“ 障碍 ”的观点。 如果任何一个视图增大,则障碍将其尺寸调整为所引用项目的最大高度或宽度。

Barriers can be vertical or horizontal and can also be created to the top, bottom, left, or right of the referenced views. The rest of the views can then constrain themselves to the barrier.

障碍可以是垂直或水平的,也可以在参考视图的顶部,底部,左侧或右侧创建。 然后,其余视图可以将自己限制在障碍上。

Now, to explore constraintlayout with barriers in compose, let’s create a simple barrier with reference to TextViewA and constraining TextViewB and TextViewC to left and right to the barrier, respectively. To be clear, let’s see the output:

现在,要探索在组合中带有障碍的constraintlayout布局,让我们参考TextViewA创建一个简单的障碍,并将TextViewBTextViewC分别约束在障碍的左侧和右侧。 为了清楚起见,让我们看一下输出:

Image for post
Barrier is created with reference to top text
参照顶部文字创建障碍

Now, let’s see the implementation part, where we have a barrier referenced to TextViewA and then aligning the rest of the view to the left and right of the barrier. Have a look:

现在,让我们看一下实现部分,其中有一个引用到TextViewA的障碍,然后将视图的其余部分与该障碍的左右对齐。 看一看:

ConstraintLayout(constraintSet = ConstraintSet {
    
    //Constains barrier related constraints
    val barrier = createRightBarrier(tag("TextViewA"))
    tag("TextViewB").right constrainTo barrier
    tag("TextViewC").left constrainTo barrier
    tag("TextViewB").apply {
        top constrainTo tag("TextViewA").bottom
    }
    tag("TextViewC").apply {
        top constrainTo tag("TextViewB").bottom
    }
    
}, modifier = Modifier.fillMaxSize()) {
    
    //Contains all the children of the layout
    Text(text = "Created barrier with this view", modifier = Modifier.tag("TextViewA")
        .padding(10.dp),
        style = TextStyle(fontSize = 15.sp))
    Text(text = "aligned left to barrier", modifier = Modifier.tag("TextViewB")
        .padding(10.dp)
        , style = TextStyle(fontSize = 15.sp))
    Text(text = "aligned right to barrier", modifier = Modifier.tag("TextViewC")
        .padding(10.dp)
        , style = TextStyle(fontSize = 15.sp))
    
}

链条 (Chains)

Chains allow us to align the views vertically or horizontal and also control the space between them, along with how the views use the space. Chains bring the traditional linear layout functionality to constraintlayout in a concise manner.

链允许我们将视图垂直或水平对齐,还可以控制它们之间的空间以及视图如何使用空间。 链以简洁的方式将传统的线性布局功能引入constraintlayout布局。

Let’s create a simple example to demonstrate the usage of chains in compose. Let’s take three text-views and align them horizontally with Spread chainstyle. Have a look:

让我们创建一个简单的示例来演示compose中链的用法。 让我们获取三个文本视图,并使用Spread chainstyle将它们水平对齐。 看一看:

ConstraintLayout(constraintSet = ConstraintSet {


    // Creating the chains
    tag("TextViewA") constrainHorizontallyTo parent
    tag("TextViewB") constrainHorizontallyTo parent
    tag("TextViewC") constrainHorizontallyTo parent
    createHorizontalChain(
        tag("TextViewA"),
        tag("TextViewB"),
        tag("TextViewC"),
        chainStyle = ConstraintSetBuilderScope.ChainStyle.Spread
    )
    
}, modifier = Modifier.fillMaxSize()) {


    // children in the layout
    Text(text = "TextViewA", modifier = Modifier.tag("TextViewA")
        .padding(10.dp),
        style = TextStyle(fontSize = 15.sp))
    Text(text = "TextViewB", modifier = Modifier.tag("TextViewB")
        .padding(10.dp)
        , style = TextStyle(fontSize = 15.sp))
    Text(text = "TextViewC", modifier = Modifier.tag("TextViewC")
        .padding(10.dp)
        , style = TextStyle(fontSize = 15.sp))
        
}

We can constrain the children in two variations:

我们可以将孩子约束为两种形式:

  • constrainHorizontallyTo: Adds constraints between left and right corresponding anchors of two layout references.

    constrainHorizo​​ntallyTo: 在两个布局参考的左,右对应锚点之间添加约束。

  • constrainVerticallyTo: Adds constraints between the top and bottom corresponding anchors of two layout references.

    constrainVerticallyTo: 在两个布局参考的顶部和底部对应锚点之间添加约束。

Coming to chainstyle, we’ve three variations:

来到chainstyle ,我们有三种变体:

  • Spread: The views are evenly distributed.

    传播:视图均匀分布。

  • Spread inside: The first and last views are aligned to the constraints on each end of the chain, and the rest are evenly distributed.

    散布在内部:第一个和最后一个视图与链两端的约束对齐,其余视图均匀分布。

  • Packed: The views are packed together.

    打包:视图打包在一起。

I hope you learn something useful, thanks for reading.

希望您能学到一些有用的东西,感谢您的阅读。

You can find me on Medium, Twitter, Quora and LinkedIn.

您可以在MediumTwitterQuoraLinkedIn上找到我。

翻译自: https://medium.com/android-dev-hacks/exploring-constraint-layout-in-jetpack-compose-67b82123c28b

jetpack

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值