当前位置:   article > 正文

Jetpack Compose实战教程(六)

Jetpack Compose实战教程(六)

Jetpack Compose实战教程(六)

第六章 没有了margin,如何区分外边距?内边距?



一、前言

我们在写xml布局的时候,经常会用到android:margin属性,毕竟除了居中以外,固定位置的偏移就得用到margin,xml中我们使用margin来设置外边距,使用padding来设置内边距。但在compose中,没有了margin属性,只有一个padding,那么我们如何设置外边距和内边距呢?

二、本章目标

能熟练的使用padding来设置内边距和外边距

友情提醒,如果各位看官有不懂的代码可以先看一下之前的章节,循序渐进,如果还是有不懂的,可以给我留言

三、开始编码

请留意:以下代码都是在清单文件中设置了横屏的

3.1 特殊情况下的margin

之所以先说特殊情况下的margin,是为了防止杠精说:明明有margin啊,只是要引入一个组件而已。没错,它就是我们第四章中提到的ConstraintLayout。 compose中的约束布局用法基本和xml一致,第四章我们也进行了一些解析,这里我们就简单上代码说明一下margin的使用

BaseTheme {
            Surface(
                modifier = Modifier.fillMaxSize(),
                color = MaterialTheme.colorScheme.background
            ) {
                ConstraintLayout(
                    Modifier
                        .fillMaxSize()
                        .background(color = Color.Yellow)) {
                    Box(modifier = Modifier
                        .size(200.dp)
                        .constrainAs(createRef()) {
                            top.linkTo(parent.top,100.dp)
                            start.linkTo(parent.start,100.dp)
                        }.background(color = Color.Blue))
                }
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这里插入图片描述

3.2 使用padding设置外边距

在使用xml代码时,我们设置外边距(margin)是在子View设置的,比如有如下代码:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="#ffff00">

    <RelativeLayout
        android:layout_width="200dp"
        android:layout_height="200dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:background="#0000ff"
        android:layout_marginTop="100dp"
        />

</androidx.constraintlayout.widget.ConstraintLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

这段代码产生的UI效果如下:
在这里插入图片描述
但在compose中,设置外边距恰恰是反过来的,它是在父View中设置,等价的代码写法如下:

BaseTheme {
            Surface(
                modifier = Modifier.fillMaxSize(),
                color = MaterialTheme.colorScheme.background
            ) {
                ConstraintLayout(
                    Modifier
                        .fillMaxSize()
                        .background(color = Color.Yellow).padding(top=100.dp)) {
                    Box(modifier = Modifier
                        .size(200.dp)
                        .constrainAs(createRef()) {
                            top.linkTo(parent.top)
                            start.linkTo(parent.start)
                        }.background(color = Color.Blue))
                }
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

这时候,有好奇的小伙伴会问了,那如果我就把这个padding写到Box 里面去,会出现什么效果呢?那么我们就来实践一下

BaseTheme {
            Surface(
                modifier = Modifier.fillMaxSize(),
                color = MaterialTheme.colorScheme.background
            ) {
                ConstraintLayout(
                    Modifier
                        .fillMaxSize()
                        .background(color = Color.Yellow)) {
                    Box(modifier = Modifier
                        .size(200.dp)
                        .constrainAs(createRef()) {
                            top.linkTo(parent.top)
                            start.linkTo(parent.start)
                        }.background(color = Color.Blue)
                        .padding(top=100.dp)
                    )
                }
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

运行结果如下:
在这里插入图片描述
可以看到,我们移除了ConstraintLayout(父View)的padding,所以Box(子View)的外间距就没有了,而我们在Box 设置的padding是应用于Box的子View的外边距,那么我们现在来给Box添加一下子View

BaseTheme {
            Surface(
                modifier = Modifier.fillMaxSize(),
                color = MaterialTheme.colorScheme.background
            ) {
                ConstraintLayout(
                    Modifier
                        .fillMaxSize()
                        .background(color = Color.Yellow)) {
                    Box(modifier = Modifier
                        .size(200.dp)
                        .constrainAs(createRef()) {
                            top.linkTo(parent.top)
                            start.linkTo(parent.start)
                        }
                        .background(color = Color.Blue)
                        .padding(top = 100.dp)
                    ){
                        Box(modifier = Modifier.size(100.dp).background(color = Color.Red))
                    }
                }
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

在这里插入图片描述
这样就很好理解了吧

3.3 使用padding设置内边距

在尝试使用padding设置内边距之前,大家需要先留意一个坑,这也是为什么我上面的例子全部是用background 来说明的原因,在xml中,我们可以给一个View设置android:background属性,然后如果再设置android:alpha是可以应用到背景上的,并且不需要关心属性设置的先后顺序,比如如下代码:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="#ffff00">

    <RelativeLayout
        android:layout_width="200dp"
        android:layout_height="200dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:background="#0000ff"
        android:alpha="0.6"
        android:layout_marginTop="100dp"
        />

</androidx.constraintlayout.widget.ConstraintLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这里插入图片描述
我们设置的颜色是蓝色,但因为设置了40%的透明度,最终和黄色的底色交融,就变成了这个灰色,但使用compose的话,必须要将alpha的属性提前,否则将失效,所以重要的话说三遍:

修饰符(Modifier)的函数调用先后顺序很重要!!

修饰符(Modifier)的函数调用先后顺序很重要!!

修饰符(Modifier)的函数调用先后顺序很重要!!

那么我们来看compose的等价代码:

BaseTheme {
            Surface(
                modifier = Modifier.fillMaxSize(),
                color = MaterialTheme.colorScheme.background
            ) {
                ConstraintLayout(
                    Modifier
                        .fillMaxSize()
                        .background(color = Color.Yellow).padding(top = 100.dp)) {
                    Box(modifier = Modifier
                        .size(200.dp)
                        .constrainAs(createRef()) {
                            top.linkTo(parent.top)
                            start.linkTo(parent.start)
                        }
                        .alpha(0.6f) //如果这行代码放在.background之后,那么将失效
                        .background(color = Color.Blue)
                    )
                }
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

好,进入整体,为了让大家更好的理解内边距,这里我不再单纯使用background,而是添加一张图片,我们先看如下代码:

BaseTheme {
            Surface(
                modifier = Modifier.fillMaxSize(),
                color = MaterialTheme.colorScheme.background
            ) {
                ConstraintLayout(
                    Modifier
                        .fillMaxSize()
                        .background(color = Color.Yellow)
                        .padding(50.dp)) {
                    Box(modifier = Modifier
                        .size(200.dp)
                        .constrainAs(createRef()) {
                            top.linkTo(parent.top)
                            start.linkTo(parent.start)
                        }
                        .background(color = Color.Blue)){
                        Image(painter = painterResource(id = R.mipmap.ic_person_detail_delete_unable),
                         contentDescription = null, modifier = Modifier.background(color = Color.Green)
                         .size(100.dp).padding(20.dp))
                    }
                }
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在这里插入图片描述
但还记得我们上面说的“修饰符(Modifier)的函数调用先后顺序很重要!!” 吗?让我们来稍微改一下代码,改变一下padding的位置

BaseTheme {
            Surface(
                modifier = Modifier.fillMaxSize(),
                color = MaterialTheme.colorScheme.background
            ) {
                ConstraintLayout(
                    Modifier
                        .fillMaxSize()
                        .background(color = Color.Yellow)
                        .padding(50.dp)) {
                    Box(modifier = Modifier
                        .size(200.dp)
                        .constrainAs(createRef()) {
                            top.linkTo(parent.top)
                            start.linkTo(parent.start)
                        }
                        .background(color = Color.Blue)){
                        Image(painter = painterResource(id = R.mipmap.ic_person_detail_delete_unable), 
                        contentDescription = null, modifier = Modifier.background(color = Color.Green)
                        .padding(20.dp).size(100.dp)) //我们将padding的调用提升至size之前
                    }
                }
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在这里插入图片描述
由于我们在设置图片的size之前先设置了padding,所以最终Image所占据的宽高都加上了padding的值,就变成了140dp,这也是实际开发中我们最容易疏忽的地方


至此,各位看官应该可以比较熟练的运用padding来设置内外边距了,实践大于阅读,一定要去实际使用才能牢固的掌握哦!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/989463
推荐阅读
相关标签
  

闽ICP备14008679号