自助建站加盟,微信公众平台如何绑定网站,企业网站新闻如何建设,网站建设人员分工表Jetpack Compose 是用于构建原生 Android 界面的新工具包#xff0c;无需修改任何 XML 布局#xff0c;也不需要使用布局编辑器。相反#xff0c;只需调用可组合函数来定义所需的元素#xff0c;Compose 编译器即会完成后面的所有工作。
简而言之#xff0c;使用Compose无需修改任何 XML 布局也不需要使用布局编辑器。相反只需调用可组合函数来定义所需的元素Compose 编译器即会完成后面的所有工作。
简而言之使用Compose不再需要xml编写页面。 可组合函数Composable function
Compose是围绕可组合函数构建的只需要描述应用界面的外观并提供数据依赖而不必关注界面的构建过程如初始化元素、将其附加到父项等。而创建Composable function只需要添加注解Composable到函数名称前。
首先我们构建创建一个应用ComposeTutorial。在AS中选择Empty Activity创建。
添加文本元素
class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {//在此处定义布局//此处的Text方法是由Compose界面库定义的文本Composable functionText(Hello world!)}}
}
setContent块定义了activity的布局在此处我们添加了Text即“Hello World!”。
自定义可组合函数
如果需要将一个函数转换为Composable function我们需要添加注解“Composable”。
修改MainActivity
class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {MessageCard(Android)//使用我们自定义的Composable function}}
}Composable//添加注解使该函数成为Composable function
fun MessageCard(name: String) {Text(text Hello $name!)
}
在AS中预览Composable function
借助Preview注解可以在AS中预览Composable function无需安装到设备或虚拟器中。
唯一要求是该注解不能用于接收参数的函数中因此在MainActivity新增如下函数
Preview
Composable
fun PreviewMessageCard() {MessageCard(Android)
}
在重新构建后该函数没有被调用应用本身不会改变但是AS对于所有添加了Preview注解的界面元素可以进行预览点击如下两个按钮之一即可 布局Layout
在此处我们实现一个简单的聊天界面显示发送者和消息内容点击消息时可缩放。
添加多个文本
class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {//向Composable function中传入发送者名称和消息内容 MessageCard(Message(Android, Jetpack Compose))}}
}//新建一个Message类包含消息发送者和消息内容
data class Message(val author: String, val body: String)Composable
fun MessageCard(msg: Message) {Text(text msg.author)Text(text msg.body)
}Preview
Composable
fun PreviewMessageCard() {MessageCard(msg Message(Lexi, Hey, take a look at Jetpack Compose, its great!))
}
这段代码会在内容视图中创建两个文本元素。不过由于未提供有关如何排列这两个文本元素的信息因此它们会相互重叠使文本无法阅读。
使用Column、Row、Box
Column直译为“圆柱体、长列”。
使用该函数修改MessageCard可以垂直排列元素使其不再重叠文本。
Composable
fun MessageCard(msg: Message) {Column {Text(text msg.author)Text(text msg.body)}
}
同样的可以使用Row函数水平排列元素而使用Box函数可以堆叠元素。
添加图片元素
使用Resource Manager从照片库中导入图片修改MessageCard
Composable
fun MessageCard(msg: Message) {//使用Row方法水平排列图片和消息Row {Image(painter painterResource(R.drawable.profile_picture),contentDescription Contact profile picture,)Column {Text(text msg.author)Text(text msg.body)}}}
配置布局Modifier
使用修饰符Modifier实现。
Compose中的每一个组件都具有Modifier属性通过他我们可以设置组件的大小、间距、外观甚至添加互动事件如点击、触摸事件。
Composable
fun MessageCard(msg: Message) {//在消息周围添加8dp的距离Row(modifier Modifier.padding(all 8.dp)) {Image(painter painterResource(R.drawable.profile_picture),contentDescription Contact profile picture,modifier Modifier//设置图片大小.size(40.dp)//将图片修剪为圆形.clip(CircleShape))//在图片和消息之间添加一个水平的空间Spacer间距为8dpSpacer(modifier Modifier.width(8.dp))Column {Text(text msg.author)// 在发送者和消息内容之间添加一个垂直的空间Spacer(modifier Modifier.height(4.dp))Text(text msg.body)}}
} Material Design
Compose 旨在支持 Material Design 原则。它的许多界面元素都原生支持 Material Design。
使用
Jetpack Compose 原生提供 Material Design 3 及其界面元素的实现。我们使用 Material Design 样式改进MessageCard可组合项的外观。
在创建ComposeTutorial项目时会同时创建一个名为“ComposeTutorialTheme”的Material主题和一个来自Material Design 3的“Surface”。我们将用到这两位来封装MessageCard函数。
Material Design是围绕Color、Typography、Shape来构建的我们将逐一添加这些元素。
修改MainActivity
class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {//使用ComposeTutorialTheme和Surface封装MessageCard函数ComposeTutorialTheme {//将给定的组件或布局填满父容器的界面Surface(modifier Modifier.fillMaxSize()) {MessageCard(Message(Android, Jetpack Compose))}}}}
}Preview
Composable
fun PreviewMessageCard() {//在Preview中也要封装沿用应用主题中定义的样式保持统一ComposeTutorialTheme {Surface {MessageCard(msg Message(Lexi, Take a look at Jetpack Compose, its great!))}}
}
颜色
Composable
fun MessageCard(msg: Message) {Row(modifier Modifier.padding(all 8.dp)) {Image(painter painterResource(R.drawable.profile_picture),contentDescription null,modifier Modifier.size(40.dp).clip(CircleShape)//为图像增加一个圆框.border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape))Spacer(modifier Modifier.width(8.dp))Column {Text(text msg.author,//通过MaterialTheme.colorScheme使用已封装主题中的颜色设置样式color MaterialTheme.colorScheme.secondary)Spacer(modifier Modifier.height(4.dp))Text(text msg.body)}}
}
Typography排版
MaterialTheme 中提供了 Material Typography 样式只需将其添加到 Text 可组合项中即可。
Composable
fun MessageCard(msg: Message) {Row(modifier Modifier.padding(all 8.dp)) {Image(painter painterResource(R.drawable.profile_picture),contentDescription null,modifier Modifier.size(40.dp).clip(CircleShape).border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape))Spacer(modifier Modifier.width(8.dp))Column {Text(text msg.author,color MaterialTheme.colorScheme.secondary,style MaterialTheme.typography.titleSmall)Spacer(modifier Modifier.height(4.dp))Text(text msg.body,style MaterialTheme.typography.bodyMedium)}}
}
Shape形状
Composable
fun MessageCard(msg: Message) {Row(modifier Modifier.padding(all 8.dp)) {Image(painter painterResource(R.drawable.profile_picture),contentDescription null,modifier Modifier.size(40.dp).clip(CircleShape).border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape))Spacer(modifier Modifier.width(8.dp))Column {Text(text msg.author,color MaterialTheme.colorScheme.secondary,style MaterialTheme.typography.titleSmall)Spacer(modifier Modifier.height(4.dp))//将消息详情封装在Surface中此时可自定义消息详情的大小、形状等布局Surface(shape MaterialTheme.shapes.medium, shadowElevation 1.dp) {Text(text msg.body,modifier Modifier.padding(all 4.dp),style MaterialTheme.typography.bodyMedium)}}}
}
启用深色主题
又称夜间模式。由于支持Material DesignJetpack Compose默认能够处理深色主题。
使用Material Design颜色、文本和背景时系统会自动适应深色背景。
//可以在文件中以单独函数的形式创建多个预览也可以向同一个函数中添加多个注解
Preview(name Light Mode)
Preview(uiMode Configuration.UI_MODE_NIGHT_YES,showBackground true,name Dark Mode
)
Composable
fun PreviewMessageCard() {ComposeTutorialTheme {Surface {MessageCard(msg Message(Lexi, Hey, take a look at Jetpack Compose, its great!))}}
} 列表和动画
创建消息列表LazyColumn、LazyRow
LazyColumn、LazyRow是Compose常见的两个组件他们的优点是可以延迟加载。他们只会加载当前可见的列表项并在滚动时动态回收其他项这使得他们适用于展示大量数据或无限滚动的列表。
在使用中会包含一个items子项。他接受LIst作为参数并且其lambda会接收到参数。系统会针对提供的List的每个项调用此lambda。
Composable
fun Conversation(messages: ListMessage) {LazyColumn {//items子项items(messages) { message -MessageCard(message)}}
}Preview
Composable
fun PreviewConversation() {ComposeTutorialTheme {Conversation(SampleData.conversationSample)}
}
在展开消息时显示动画效果
为了存储某条消息是否已展开我们使用remember和mutableStateOf函数。
可组合函数可以使用remember将本地状态存储到内存中并跟踪传递给mutableStateOf的值的变化。而mutableStateOf函数可以在可组合函数内部创建一个可变的状态并将其与UI组件进行绑定。当状态值发生变化时Compose会自动重绘相关的组件。
class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {ComposeTutorialTheme {Conversation(SampleData.conversationSample)}}}
}Composable
fun MessageCard(msg: Message) {Row(modifier Modifier.padding(all 8.dp)) {Image(painter painterResource(R.drawable.profile_picture),contentDescription null,modifier Modifier.size(40.dp).clip(CircleShape).border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape))Spacer(modifier Modifier.width(8.dp))// 在此变量中跟踪当前消息是否展开var isExpanded by remember { mutableStateOf(false) }// 当点击该消息时改变展开状态Column(modifier Modifier.clickable { isExpanded !isExpanded }) {Text(text msg.author,color MaterialTheme.colorScheme.secondary,style MaterialTheme.typography.titleSmall)Spacer(modifier Modifier.height(4.dp))Surface(shape MaterialTheme.shapes.medium,shadowElevation 1.dp,) {Text(text msg.body,modifier Modifier.padding(all 4.dp),// 若展开全部显示不展开最大显示一行maxLines if (isExpanded) Int.MAX_VALUE else 1,style MaterialTheme.typography.bodyMedium)}}}
} 注需要添加以下导入内容才能正确使用 Kotlin 的委托属性语法by 关键字import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue 使用by关键字是避免每次都访问value属性的好方法。 同时需要注意的是我们应该只在可组合函数的作用域之外改变状态。这是因为可组合项可以频繁运行、且以任何顺序执行。此处我们可以在clickable中修改isExpanded的值是因为clickable不是可组合函数。 除了remember关键字我们还可以使用rememberSaveable它与前者类似但存储的值可以在重新创建activity和进程后保存下来。需要注意的是rememberSaveable适用于UI状态如购物车的商品数量或选定的标签页但不适用于过渡动画状态等。
同时我们可以加入颜色在消息缩放时改变消息的颜色。但不能只是简单的改变消息的背景颜色我们应当加入动画使得变化时逐步更改。
相同的在点击缩放时我们也可以加上动画使得缩放更加顺滑。
Composable
fun MessageCard(msg: Message) {Row(modifier Modifier.padding(all 8.dp)) {Image(painter painterResource(R.drawable.profile_picture),contentDescription null,modifier Modifier.size(40.dp).clip(CircleShape).border(1.5.dp, MaterialTheme.colorScheme.secondary, CircleShape))Spacer(modifier Modifier.width(8.dp))var isExpanded by remember { mutableStateOf(false) }// 该变量会逐步更新颜色animateColorAsState函数实现颜色之间的过渡动画效果val surfaceColor by animateColorAsState(if (isExpanded) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surface,)Column(modifier Modifier.clickable { isExpanded !isExpanded }) {Text(text msg.author,color MaterialTheme.colorScheme.secondary,style MaterialTheme.typography.titleSmall)Spacer(modifier Modifier.height(4.dp))Surface(shape MaterialTheme.shapes.medium,shadowElevation 1.dp,color surfaceColor,//加入animateContentSize给缩放加入动画更加顺滑modifier Modifier.animateContentSize().padding(1.dp)) {Text(text msg.body,modifier Modifier.padding(all 4.dp),maxLines if (isExpanded) Int.MAX_VALUE else 1,style MaterialTheme.typography.bodyMedium)}}}
}