最近突然看到了这个新东西,查了一下是谷歌在19年的IO大会上宣布的一个新的构建UI的工具库,这几天无聊就试着建了个新项目将这个工具库导进去试了一下,先说一下我个人的感受:本人之前接触过flutter,这个新工具库的UI构建方式是跟flutter一模一样的,开发者不需要在xml里画界面了,也许这就是未来构建UI的主流方法吧,接下来主要来记录一下本人初次接触这个工具库的一些实践,对于不了解flutter的朋友来说我接下来描述的内容可能有点不太了解,可以先去了解一下flutter。如果对这个库有兴趣的朋友可以直接点击此处去官网了解一下。 需要提前说明的是,这个工具类在Android studio 4.0预览版是可以对你构造出来对UI进行预览的,官方也说明只有在这个版本才能获得compose开发的最好体验,如果不是这个版本的话,就没办法对UI进行预览了。
在Android studio 4.0预览版里是可以在新建工程的时候直接创建Compose Activity,如果跟我一样没有用这个版本的Android studio的朋友就在进行以下配置了 在module的build.gradle里进行配置
android{ defaultConfig { ..... } buildFeatures { compose true } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } composeOptions { kotlinCompilerExtensionVersion "0.1.0-dev09" } }然后导入依赖
implementation 'androidx.ui:ui-framework:0.1.0-dev10' implementation 'androidx.ui:ui-tooling:0.1.0-dev10' implementation 'androidx.ui:ui-layout:0.1.0-dev10' implementation 'androidx.ui:ui-material:0.1.0-dev10'这里当前写这篇文章时候发布的最新版本,如果要知道目前最新版本请去官网上看。
在根目录下的build.gradle里写入
allprojects { repositories { maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' } } }这就算导入好了
直接放代码
class MainActivity : AppCompatActivity(){ override fun onCreate(savedInstanceState: Bundle?){ super.onCreate(savedInstanceState) setContent { Text("hello") } } }没得错,将setContentView()方法用setContent()这个扩展函数来代替了,之后只需要在里面声明控件就好了。里面一些基本的控件命名跟flutter都差不多,比如Text,Colum,Row等,当然也只是部分,还有一大部分等控件命名还是不一样的,比如处理点击的控件在flutter中有GestureDetector,InkWell等,在Compose里使用了Clickable
setContent { Clickable( modifier = Modifier.padding(top = 10.dp), onClick = { //点击事件 }, children = { ... } ) }另外Compose支持使用函数构造UI 比如以下两种写法是共通的 写法一:
setContent { Column { Text("Compose 初试", style = MaterialTheme.typography.h5) Clickable( modifier = Modifier.padding(top = 10.dp), onClick = { Toast.makeText(this@MainActivity,"click",Toast.LENGTH_SHORT).show() }, children = { Text( ... ) } ) } }写法二:
setContent { Column{ initView() } } ..... @Composable fun initView() { Text("Compose 初试", style = MaterialTheme.typography.h5) Clickable( modifier = Modifier.padding(top = 10.dp), onClick = { Toast.makeText(this@MainActivity,"click",Toast.LENGTH_SHORT).show() }, children = { Text( .... ) } ) }只要使用@Composable注解就可以让这个函数成为Compose函数,这种写法可以把规划为同一区域的控件单独抽取出来放在一个函数中,逻辑会更加清晰一些。
了解flutter的朋友知道flutter中刷新UI只要调用setState()就可以了,那么Compose怎么刷新UI的呢?我一开始也有点懵,找了半天后发现了这个操作:
@Model class MainModel { var count = 0 var check = false var tableData = arrayListOf<String>("good","yes") }只要对类使用了@Model注解,然后对这个类中的值进行改动的时候就会更新UI了,比如:
class MainActivity : AppCompatActivity() { private val model : MainModel by lazy(::MainModel) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent{ Clickable( modifier = Modifier.padding(top = 10.dp), onClick = { Toast.makeText(this@MainActivity,"click",Toast.LENGTH_SHORT).show() model.count ++ }, children = { Text( text = if (model.count == 0) { "点击此处" }else{ "点击此处${model.count}" } ) } ) } } @Model class MainModel { var count = 0 } }看了以下Compose提供的控件发现没有类似与ListView或者RecyclerView的控件,也没有flutter里面那样的List控件,Compose的控件里有这么两个控件VerticalScroller和HorizontalScroller,听名字就知道是用来纵向/横向滑动的,然后我就这么试了一下:
setContent { Column ( modifier = Modifier.padding(10.dp) ) { VerticalScroller(modifier = Modifier.fillMaxWidth().fillMaxHeight()) { Column { for (item in model.tableData) { Card { Text(item) } } } } } }这个model.tableData是我在我注解的Model类中声明的一个字符串数组,这样的话只要对这个数组进行增删这个Colum就可以像list一样了。
这还是一个比较新的库,里面的控件也不多,这种UI构建方式也许对没接触过flutter的朋友有点陌生,但是个人觉得是比较值得尝试的。