Jetpack Compose

Jetpack Compose:声明式UI框架

(Composition over inheritance) 组合优于继承

1. 什么是Compose,有什么优势?

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进行修改

2. 使用

我是基于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
}

3. 基本UI和使用

Jetpack Compose_第1张图片
yyyyy
VerticalScroller - 纵向滑动
HorizontalScroller - 横向滑动
Column - 纵向布局
Row - 横向布局
MaterialTheme - 主题
Surface - 背景色
FlexColumn - 权重布局
TopAppBar - 标题栏
DrawImage - 图片
Clip - 圆角
Container - 容器
Text - 文本
Divider - 线
HeightSpacer - 高度填充
WidthSpacer - 宽度填充
TabRow - 导航栏
Tab - 导航标题
Button - 按钮
Checkbox - 选项框
Card - 卡片布局
Ripple - 水波纹
repeat - 循环
VectorImageButton - Vector图片按钮

Jetpack Compose_第2张图片

代码

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()
            }
        }
    }
}

你可能感兴趣的:(Android)