Jetpack Compose 常用控件使用

508 阅读1分钟

集成

android 节点的配置

android {

    buildFeatures {
        compose true
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    composeOptions {
        kotlinCompilerExtensionVersion '1.1.1'
    }
}

添加 Jetpack Compose 工具包依赖项

dependencies {
  
    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.material:material:$compose_version"
    implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
    implementation 'androidx.activity:activity-compose:1.3.1'
}

详细集成教程可以从 developer.android.com/jetpack/com… 中查看

基本控件使用

Text

文本控件 , 类似于 TextView 基本使用

    Text(
        text = "Hello World!",
        color = Color.Blue,
        modifier = Modifier.padding(20.dp)
    

效果图如下 image.png

Button

  Button(
      onClick = {  }  
  ) {
      Text("Button")
  }

Image

基本使用 , 从_Resource 获取图片_

  Image(
      modifier = Modifier.size(20.dp).align(Alignment.TopEnd) ,
      painter = painterResource(R.drawable.ic_launcher_background),
      contentDescription = "",
  )

Box

类似于View 体系中的帧布局 在Box 中放一个文本和一张图片 , 分别放置左上角和右上角 , fillMaxSize 表示充满父布局

 Box(modifier = Modifier.fillMaxSize()) {
            Text(
                text = "Hello World!",
                color = Color.Blue,
                modifier = Modifier.padding(20.dp).align(Alignment.TopStart)
            )
            Image(
                modifier = Modifier.size(100.dp).align(Alignment.TopEnd) ,
                painter = painterResource(R.drawable.ic_launcher_background),
                contentDescription = "Contact profile picture",
            )
        }

预览图 image.png

Row

类似于水平走向的线型布局 , 常用属性如下 image.png Arrangement的值和对应效果如下: eaf39ee39ad84a1ebf47acfe8e58cd01.gif 在Row 中添加9个Text , 并且weight 权重 =1 , padding 为 2

            Row {
                for (i in 1..9) {
                    Text(
                        text = "$i",
                        color = Color.White,
                        textAlign = TextAlign.Center,
                        modifier = Modifier
                            .padding(2.dp)
                            .weight(1f)
                            .background(Color.Black)
                    )
                }
            }

效果图 image.png

Column

类似于垂直走向的线型布局 , 基本使用和 Row 类似

LazyRow

可滚动 水平方向 List 布局 , 类似于水平使用的RecyclerView 在LazyRow 中添加9个width 为100dp的item

            LazyRow {
                for (i in 1..9) {
                    item {
                        Text(
                        text = "$i",
                        color = Color.White,
                        textAlign = TextAlign.Center,
                        modifier = Modifier
                            .padding(2.dp)
                            .width(100.dp)
                            .background(Color.Black)
                    ) }
                }
            }

220713 165733.gif

LazyColumn

和 LazyRow 使用类似

高级控件使用

ConstraintLayout

集成

    implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"

使用基本和View体系中的ConstraintLayout 类似 基本api

  • createRefs() 或 createRefFor(),创建引用 , 每个可组合项都需要有与之关联的引用
  • constrainAs(xxx) 约束条件 , 将引用作为参数,可在主体 lambda 中指定其约束条件
  • 约束条件是使用 linkTo() 指定
  • parent获取 父控件的引用

在ConstraintLayout 中 为 Button 和 Text 添加约束

    ConstraintLayout {
        val (button, text) = createRefs()
        Button(
            onClick = { },
            modifier = Modifier.constrainAs(button) {
                top.linkTo(parent.top, margin = 16.dp)
            }
        ) {
            Text("Button")
        }

        Text("Text", Modifier.constrainAs(text) {
            top.linkTo(button.bottom, margin = 16.dp)
        })
    }

image.png ConstraintSet 约束集 上面的例子也可以用ConstraintSet 来代替 createRefs

private fun decoupledConstraints(margin: Dp): ConstraintSet {
    return ConstraintSet {
        val button = createRefFor("button")
        val text = createRefFor("text")

        constrain(button) {
            top.linkTo(parent.top, margin = margin)
        }
        constrain(text) {
            top.linkTo(button.bottom, margin)
        }
    }
}

然后使用 Modifier.layoutId("button") , Modifier.layoutId("text") 给控件指定id , 就能使用约束集了

val constraints=  decoupledConstraints(20.dp)
ConstraintLayout(constraints) {
            Button(
                onClick = { /* Do something */ },
                modifier = Modifier.layoutId("button")
            ) {
                Text("Button")
            }

            Text("Text", Modifier.layoutId("text"))
        }

Scaffold

用于将 Material 组件组合成常见的界面 , 比如app 主界面 Scaffold 内部的属性如下

fun Scaffold(
    modifier: Modifier = Modifier,
    scaffoldState: ScaffoldState = rememberScaffoldState(),
    topBar: @Composable () -> Unit = {},
    bottomBar: @Composable () -> Unit = {},
    snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) },
    floatingActionButton: @Composable () -> Unit = {},
    floatingActionButtonPosition: FabPosition = FabPosition.End,
    isFloatingActionButtonDocked: Boolean = false,
    drawerContent: @Composable (ColumnScope.() -> Unit)? = null,
    drawerGesturesEnabled: Boolean = true,
    drawerShape: Shape = MaterialTheme.shapes.large,
    drawerElevation: Dp = DrawerDefaults.Elevation,
    drawerBackgroundColor: Color = MaterialTheme.colors.surface,
    drawerContentColor: Color = contentColorFor(drawerBackgroundColor),
    drawerScrimColor: Color = DrawerDefaults.scrimColor,
    backgroundColor: Color = MaterialTheme.colors.background,
    contentColor: Color = contentColorFor(backgroundColor),
    content: @Composable (PaddingValues) -> Unit
) {

topBar: 标题栏

bottomBar: 底部导航栏

content : 内容

使用Scaffold 快速搭建一个应用主界面

      Scaffold(
          topBar = {
              Row(
                  horizontalArrangement = Arrangement.SpaceBetween,
                  modifier = Modifier.fillMaxWidth()
                      .height(60.dp).background(Color.Blue).padding(10.dp)
              ) {
                  Icon(
                      modifier = Modifier.align(Alignment.CenterVertically),
                      imageVector = Icons.Default.Close,
                      contentDescription = null,
                      tint = Color.White
                  )
                  Text(
                      color = Color.White,
                      modifier = Modifier.align(Alignment.CenterVertically), text = "标题"
                  )
                  Icon(
                      modifier = Modifier.align(Alignment.CenterVertically),
                    imageVector = Icons.Default.Close,
                    contentDescription = null,
                    tint = Color.White
                )
            }
          },
          bottomBar = {
              BottomNavigation() {
                  for(i in 0..3){
                      BottomNavigationItem(
                          onClick = {},
                          selected=false ,
                          icon = {  Icon(
                              modifier = Modifier.align(Alignment.CenterVertically),
                              imageVector = Icons.Default.Close,
                              contentDescription = null,
                              tint = Color.White
                          )} ,
                      label = {
                          Text ("$i")
                      })
                  }
              }
          }) {
          Box(modifier =Modifier.fillMaxSize()) {
              Text( color = Color.Black ,modifier = Modifier.align(Alignment.Center),text = "内容")
          }

      }

预览图 image.png