(Composition over inheritance) 组合优于继承
Jetpack Compose 是一个现代工具包,旨在简化UI开发。它结合了反应式编程模型和Kotlin编程语言的简洁性和易用性。它是完全声明性的,Compose的口号就是消灭xml,在撸过代码之后总结总体上UI的结构和Flutter一致,只有在语法上存在部分差异,因为我是基于dev2的版本体验的,所以在页面的体验上并不是很流畅,
而且Compose是没有view复用的,可能也是较早期的版本可用的资源也不是很多
在使用上Compose可以让你更专心的处理业务,因起特性声明UI组件和业务都在class中,较现在的xml模式可以省去很多findViewbyId等一系列绑定的操作
在更新UI上Compose也有类似Flutter的Provide一样的更新机制,当基础数据更改时,框架会自动调用这些功能,从而更新视图层次结构
Compose在UI上改动是非常大的不是采用了传统UI的多层继承结构,而是多个View组合成一个View
更新数据只要在使用的实体上面加注解@Model在更新实体的同时会通知UI进行修改
我是基于Android Studio 3.5.1 / build:gralde 3.5.1 / gradle 5.4.1 / compse 0.1.0-dev02 / kotlin 1.3.60-eap-76 版本进行开发的
基本核心库 (其中androidx.ui为Compose.UI库)
androidx.compose:compose-runtime
androidx.ui:ui-framework
androidx.ui:ui-layout
androidx.ui:ui-material
androidx.ui:ui-tooling
androidx.appcompat:appcompat
androidx.activity:activity-ktx
androidx.core:core-ktx
com.pinterest:ktlint
Android studio 4.0以上要打开开关 (Compose对4.0以下版本部分功能不支持)
buildFeatures {
compose true
}
VerticalScroller - 纵向滑动
HorizontalScroller - 横向滑动
Column - 纵向布局
Row - 横向布局
MaterialTheme - 主题
Surface - 背景色
FlexColumn - 权重布局
TopAppBar - 标题栏
DrawImage - 图片
Clip - 圆角
Container - 容器
Text - 文本
Divider - 线
HeightSpacer - 高度填充
WidthSpacer - 宽度填充
TabRow - 导航栏
Tab - 导航标题
Button - 按钮
Checkbox - 选项框
Card - 卡片布局
Ripple - 水波纹
repeat - 循环
VectorImageButton - Vector图片按钮
代码
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.Composable
import androidx.compose.Model
import androidx.compose.unaryPlus
import androidx.ui.core.*
import androidx.ui.foundation.DrawImage
import androidx.ui.foundation.HorizontalScroller
import androidx.ui.foundation.VerticalScroller
import androidx.ui.foundation.shape.corner.RoundedCornerShape
import androidx.ui.graphics.Color
import androidx.ui.layout.*
import androidx.ui.material.*
import androidx.ui.material.ripple.Ripple
import androidx.ui.material.surface.Card
import androidx.ui.material.surface.Surface
import androidx.ui.res.imageResource
import androidx.ui.text.TextStyle
import androidx.ui.text.style.TextOverflow
import androidx.ui.tooling.preview.Preview
import com.example.jetnews.R
/**
* @fileName: YTestActivity
* @date: 2019/11/21 18:12
* @auther: YuanShuai
* @tag: class//
* @describe:
**/
class YTestActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApp {
layout()
}
}
}
@Composable //ComposeUI
fun layout(
nums: List<String> = listOf("Hello Compose !", "Two Container !"),
counterState: NumState = NumState()
) {
//纵向滑动布局
VerticalScroller {
//纵向布局
Column {
//循环添加
for (num in nums) {
Greeting(num, counterState)
}
}
}
}
@Composable //ComposeUI
fun MyApp(children: @Composable() () -> Unit) {
//Material主题
MaterialTheme {
//自定义主题
//CustomTheme {
//背景色
Surface(color = Color(0xffffffff)) {
//权重布局
FlexColumn {
inflexible {
//标题栏
TopAppBar(
title = { Text("AppBar") },
navigationIcon = {
//Vector图片按钮
VectorImageButton(R.drawable.ic_back) {
Toast.makeText(this@YTestActivity, "back", Toast.LENGTH_SHORT)
.show()
}
}
)
}
flexible(flex = 1f) {
children()
}
}
}
}
}
@Preview("Test Preview") //浏览视图
@Composable //ComposeUI
private fun Greeting(
text: String,
counterState: NumState
) {
val image = +imageResource(R.drawable.duia_bg)
val image2 = +imageResource(R.drawable.duia)
//纵向布局
Column(
crossAxisSize = LayoutSize.Wrap,
modifier = Spacing(10.dp)
) {
//容器
Container(expanded = true, height = 220.dp) {
//圆角
Clip(shape = RoundedCornerShape(8.dp)) {
//图片
DrawImage(image)
Container(expanded = true, height = 100.dp, width = 100.dp) {
DrawImage(image2)
}
}
}
//高度填充
HeightSpacer(10.dp)
//文本
Text(text, style = (+themeTextStyle { h6 }).withOpacity(0.8f))
HeightSpacer(10.dp)
//分割线
Divider(color = Color(0x33333333))
HeightSpacer(10.dp)
Container(expanded = true) {
//文本
Text(
"Kotlin Compose !",
style = (+themeTextStyle { body2 }).withOpacity(0.47f)
)
}
HeightSpacer(10.dp)
Divider(color = Color(0x23330033))
HeightSpacer(10.dp)
Container(expanded = true, alignment = Alignment.CenterRight) {
Text(
"Alignment !",
style = TextStyle(color = Color(0xFF936112), fontSize = 18.sp)
)
}
HeightSpacer(10.dp)
Divider(color = Color(0x23330033))
HeightSpacer(10.dp)
Text("设置文本行数////设置文本行数////设置文本行数////设置文本行数////设置文本行数////设置文本行数////设置文本行数" +
"////设置文本行数////设置文本行数////设置文本行数////设置文本行数////设置文本行数////设置文本行数////设置文本行数" +
"////设置文本行数////设置文本行数//",
maxLines = 2,
overflow = TextOverflow.Ellipsis,
style = +themeTextStyle { body2 })
HeightSpacer(10.dp)
Divider(color = Color(0x23330033))
HeightSpacer(10.dp)
//横向布局
Row(crossAxisAlignment = CrossAxisAlignment.Center) {
Surface(color = Color.Blue) {
Clip(shape = RoundedCornerShape(8.dp)) {
Text(
"背景色",
modifier = Spacing(20.dp),
style = TextStyle(color = Color(0xFFFFFFFF), fontSize = 20.sp)
)
}
}
//宽度填充
WidthSpacer(10.dp)
Counter(counterState)
WidthSpacer(10.dp)
Form(true)
Form(false)
}
HeightSpacer(10.dp)
Divider(color = Color(0x23330033))
HeightSpacer(10.dp)
Row(modifier = ExpandedWidth, crossAxisAlignment = CrossAxisAlignment.Center) {
textView(Flexible(1f), Color.Magenta, "权重-1")
textView(Flexible(2f), Color.DarkGray, "权重-2")
textView(Flexible(5f), Color.Red, "权重-5")
}
HeightSpacer(10.dp)
Divider(color = Color(0x23330033))
HeightSpacer(10.dp)
//横向滑动布局
HorizontalScroller {
Row {
//循环5次
repeat(5) {
//卡片布局
Card(shape = RoundedCornerShape(10.dp)) {
//水波纹
Ripple(bounded = true) {
Surface(color = Color.LightGray) {
Container(width = 150.dp, height = 150.dp) {
Column {
Container(height = 110.dp, expanded = true) {
DrawImage(image)
}
Text(
text = "TitleTitleTitleTitleTitleTitleTitleTitleTitleTitleTitleTitleTitleTitleTitleTitleTitleTitleTitleTitleTitleTitleTitle",
style = (+themeTextStyle { subtitle1 }).withOpacity(
0.87f
),
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
}
}
}
}
}
WidthSpacer(16.dp)
}
}
}
HeightSpacer(10.dp)
//导航栏
TabRow(items = listOf("导", "航", "栏"), selectedIndex = 0) { index, text ->
//标题
Tab(text = text, selected = 0 == index) {
Toast.makeText(this@YTestActivity, "index=$index", Toast.LENGTH_SHORT).show()
}
}
}
}
@Composable //ComposeUI
fun textView(flex: Modifier, color: Color, text: String) {
Column(modifier = flex) {
Surface(color = color) {
Text(
text,
style = TextStyle(color = Color(0xFFFFFFFF), fontSize = 20.sp)
)
}
}
}
/**
* 按钮点击
*/
@Composable //ComposeUI
fun Counter(state: NumState) {
//按钮
Button(
text = "已经点了${state.count}次了",
onClick = {
state.count++
},
style = ContainedButtonStyle(color = if (state.count > 0) Color.Green else +themeColor { primary })
)
}
/**
* 选择框
*/
@Composable
fun Form(state: Boolean) {
var formState = FormState(state)
//选择框
Checkbox(
checked = formState.optionChecked,
onCheckedChange = { newState -> formState.optionChecked = newState }
)
}
@Model //@Model修饰的实体修改的同时会通知UI自动更新
class FormState(var optionChecked: Boolean)
@Model
class NumState(var count: Int = 0)
val green = Color(0xFF1EB90)
val grey = Color(0xFF26282F)
private val themeColros = MaterialColors(
primary = green,
surface = grey,
onSurface = Color.White
)
/**
* 自定义主题
*/
@Composable
fun CustomTheme(children: @Composable() () -> Unit) {
MaterialTheme(colors = themeColros) {
val textStyle = TextStyle(color = Color.Red)
CurrentTextStyleProvider(value = textStyle) {
children()
}
}
}
}