前言

Jetpack Compose 被官方称为 Android 用于构建原生 UI 的现代工具包,它简化并加速了 Android 上的 UI 开发,并以更少的代码、强大的工具和直观的 Kotlin API 快速将应用程序变为现实。

谷歌推出了用于构建 Android 应用程序的最新工具包 Jetpack Compose,预计将取代 Android View System。它不是唯一可用的声明性 UI 概念。React Native、Flutter 和 Swift UI 都基于声明式 UI 概念。

在这里,在本文中,我试图帮助新手了解使用 Android Studio 的 Jetpack Compose 的基础知识。写这篇文章时稳定的 android studio 版本是 Chipmunk。让我们上车吧。

第一个 Jetpack Compose 项目

创建 compose 项目的最佳方式是通过 Android Studio 中的 New Project,如下图所示。

android 使用 compose android compose ui_ui


android 使用 compose android compose ui_android 使用 compose_02


android 使用 compose android compose ui_android 使用 compose_03


android 使用 compose android compose ui_android 使用 compose_04


创建新项目并成功构建后,Hello Android在预览面板中如上图所示。

让我们分解最初的项目并尝试了解一些基础知识。

项目结构

生成的 android 项目具有以下文件夹结构,应用程序以 MainActivity 以及与主题相关的文件(如Color.kt、Theme.kt、Type.kt.

android 使用 compose android compose ui_ui_05


android 使用 compose android compose ui_ui_06

可组合函数

可组合函数必须@Composable在顶部使用注释。这些函数没有返回类型,但可以有多个函数参数。可组合函数内部的内容被渲染以进行应用程序布局设计。

@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}

预习

如果任何可组合函数进一步用@Preview.

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    FirstComposeAppTheme {
        Greeting("Android")
    }
}

android 使用 compose android compose ui_android_07


如果showSystemUI在预览中设置为 true。设计预览显示在 Android 设备框架中。

@Preview(showBackground = true, showSystemUi = true)
@Composable
fun DefaultPreview() {
    FirstComposeAppTheme {
        Greeting("Android")
    }
}

android 使用 compose android compose ui_kotlin_08

MainActivity.kt

此文件(活动类)是使用 Compose UI 的起点。这个活动类也必须在app/src/main/AndroidManifest.xmlas launcher 活动中定义。Compose 代码必须写在setContentdsl 函数中。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            FirstComposeAppTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Greeting("Android")
                }
            }
        }
    }
}

主题.kt

此文件用于为应用程序内部使用的可组合功能(UI 组件)定义配色方案和主题。在这里,定义了一个可组合函数来为子可组合项提供主题包装器。此包装器有助于将定义的主题继承给子组合 UI 组件。

android 使用 compose android compose ui_android 使用 compose_09

@Composable
fun FirstComposeAppTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    // Dynamic color is available on Android 12+
    dynamicColor: Boolean = true,
    content: @Composable () -> Unit
) {
    val colorScheme = when {
        dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
            val context = LocalContext.current
            if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
        }
        darkTheme -> DarkColorScheme
        else -> LightColorScheme
    }
    val view = LocalView.current
    if (!view.isInEditMode) {
        SideEffect {
            (view.context as Activity).window.statusBarColor = colorScheme.primary.toArgb()
            ViewCompat.getWindowInsetsController(view)?.isAppearanceLightStatusBars = darkTheme
        }
    }

    MaterialTheme(
        colorScheme = colorScheme,
        typography = Typography,
        content = content
    )
}

基本的可组合组件

显示文本并提供语义/可访问性信息的高级元素。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            FirstComposeAppTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    LayoutBasics()
                }
            }
        }
    }
}

@Composable
fun LayoutBasics() {
    Text(text = "Hello Jetpack!")
}

@Preview(showBackground = true, showSystemUi = false)
@Composable
fun DefaultPreview() {
    FirstComposeAppTheme {
        LayoutBasics()
    }
}

这里,LayoutBasics是一个可组合函数,它包含另一个可组合函数Text并呈现如下图所示的文本Hello Jetpack!。

android 使用 compose android compose ui_android 使用 compose_10


android 使用 compose android compose ui_android 使用 compose_11


该Text函数有各种参数来定义颜色、字体大小、字体类型、字体样式、文本对齐方式等。这里是一个两行文本的示例,溢出省略号和其他各种样式。

@Composable
fun LayoutBasics() {
    val longText =
        "Hello Jetpack!\nThe quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog"
    Text(
        text = longText,
        modifier = Modifier.padding(16.dp),
        color = Color.Red,
        fontSize = 20.sp,
        fontStyle = FontStyle.Italic,
        letterSpacing = 5.sp,
        textDecoration = TextDecoration.Underline,
        textAlign = TextAlign.Start,
        overflow = TextOverflow.Ellipsis,
        softWrap = true,
        maxLines = 2,
        style = TextStyle.Default,
    )
}

@Preview(showBackground = true, showSystemUi = false)
@Composable
fun DefaultPreview() {
    FirstComposeAppTheme {
        LayoutBasics()
    }
}

android 使用 compose android compose ui_android 使用 compose_12

图片

创建一个可组合的布局并绘制给定的来源,如画家。可绘制图像资源在画家资源内部传递,并用作Image可组合的参数。

@Composable
fun LayoutBasics() {
    // image path: app/src/main/res/drawable/jetpack_compose.png
    Image(
        painter = painterResource(R.drawable.jetpack_compose),
        contentDescription = null,
        modifier = Modifier
            .padding(16.dp)
            .size(100.dp)
            .border(1.dp, MaterialTheme.colorScheme.secondary, RoundedCornerShape(8.dp))
    )
}

@Preview(showBackground = true, showSystemUi = false)
@Composable
fun DefaultPreview() {
    FirstComposeAppTheme {
        LayoutBasics()
    }
}

android 使用 compose android compose ui_android_13


矢量图像也可以像下面的示例一样呈现。

@Composable
fun LayoutBasics() {
    Image(
        imageVector = Icons.Filled.AccountCircle,
        contentDescription = null, // decorative
        modifier = Modifier.size(40.dp),
        colorFilter = ColorFilter.tint(color = Color.LightGray),
        contentScale = ContentScale.Fit
    )
}

android 使用 compose android compose ui_kotlin_14

一种可组合的布局,将其子项按水平顺序放置。

Row用于以水平方式并排放置组件的组合。这是连续图像图标的示例。

@Composable
fun LayoutBasics() {
   Row {
       ImageIcon()
       ImageIcon()
       ImageIcon()
   }
}

@Composable
fun ImageIcon(){
    Image(
        imageVector = Icons.Filled.AccountCircle,
        contentDescription = null, // decorative
        modifier = Modifier.size(40.dp),
        colorFilter = ColorFilter.tint(color = Color.Gray),
        contentScale = ContentScale.Fit
    )
}

@Preview(showBackground = true, showSystemUi = false)
@Composable
fun DefaultPreview() {
    FirstComposeAppTheme {
        LayoutBasics()
    }
}

android 使用 compose android compose ui_kotlin_15

柱子

一种可组合的布局,将其子项按垂直顺序放置。

一个Column可组合的,用于以垂直方式一个接一个地放置组件。这是列中的文本示例。

@Composable
fun LayoutBasics() {
   Column {
       Text("First Text")
       Text("Second Text")
       Text("Third Text")
       Text("Fourth Text")
   }
}

@Preview(showBackground = true, showSystemUi = false)
@Composable
fun DefaultPreview() {
    FirstComposeAppTheme {
        LayoutBasics()
    }
}

android 使用 compose android compose ui_android jetpack_16

行列组合

Row 和 Column 可以组合起来表示 UI 组件。让我们看下面的例子。该列包含一个图像和行。内行包含一个图像和另一列。

@Composable
fun LayoutBasics() {
    Column(
        Modifier
            .background(Color.LightGray)
            .padding(16.dp)
    ) {

        Image(
            painter = painterResource(R.drawable.begin_cup),
            contentDescription = null,
            modifier = Modifier.clip(RoundedCornerShape(8.dp)),
            contentScale = ContentScale.Fit
        )

        Row(
            modifier = Modifier
                .background(Color.White)
                .fillMaxWidth()
                .padding(PaddingValues(16.dp))
        ) {
            Image(
                imageVector = Icons.Default.AccountCircle,
                modifier = Modifier
                    .size(40.dp)
                    .clip(CircleShape)
                    .background(Color.LightGray),
                contentDescription = null,
                contentScale = ContentScale.Fit,
                colorFilter = ColorFilter.tint(color = Color.Green)
            )

            Spacer(modifier = Modifier.width(16.dp))

            Column {
                Text(text = "Begin Cup", fontWeight = FontWeight.Bold)
                Text(text = "A good morning coffee")
            }
        }
    }
}

@Preview(showBackground = true, showSystemUi = true)
@Composable
fun DefaultPreview() {
    FirstComposeAppTheme {
        LayoutBasics()
    }
}

android 使用 compose android compose ui_android 使用 compose_17


在本文中,我介绍了 Jetpack Compose 的一些基础知识。将来,我将介绍更高级的主题。敬请关注!