效果如下:
代码很简单,但是这是一个函数,用Composable修饰,就表示一个UI状态,只需要在MainActivity的onCreate()里面调用setContent()就可以:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent { TextViewDemo() }
}
}
复制代码
这就完事了。
到这里,我们可以了解到:
-
1 Compose是声明式UI,不是传统的命令式UI,不是拿着View去setXXX(),而是用函数去描述一种UI状态。
-
2 Compose采用的是属性细化和行为隔离的思想,比如demo里面,text就是Text直接的属性,而background是modifier的一个属性,因为像图片Image就没有text属性,但是却有background属性,所以Compose就将公有属性提取到Modifier中,将独有属性绑定到View自身,这就是一种属性细化的思想,而且点击事件是在Modifier中,也就是通过Modifier来控制行为,这就是行为和属性分开。换句话说,View本身只负责描述自身固有属性,Modifier负责描述扩展属性和行为,这样设计更人性化,变相降低了耦合。
我们来看个功能,这是谷歌的Android Study Jam 结课小测验,要求实现一个Searchbar。
先看效果:
很简单,输入关键词,点击搜索,就列出包含关键词的条目,关键词为空就列出全部,如果我们用原生实现,可能需要写一个RecyclerView,一个Adapter,一个ViewHolder…,我们来看Compose版本的:
1 实现上方Searchbar
@Composable
fun SearchBar(onSearch: (keyword: String) -> Unit) {
var value by remember { mutableStateOf("") }
OutlinedTextField(
label = { Text(text = “Please input keyword”) },
value = value,
onValueChange = { value = it },
modifier = Modifier
.padding(horizontal = 16.dp)
.fillMaxWidth(),
singleLine = true,
textStyle = TextStyle(color = Color.DarkGray, fontWeight = FontWeight.W700),
trailingIcon = @Composable { Image(imageVector = Icons.Filled.Clear, contentDescription = null, Modifier.clickable { value = “” }) },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
keyboardActions = KeyboardActions(onSearch = { onSearch.invoke(value) }),
)
}
复制代码
函数接收一个onSearch()方法,传递一个String;OutlinedTextField可以理解为EditText,value就等价于EditText的text属性,trailingIcon表示尾部图标,就是那个关闭的X,点击它的时候,我们把value设置为空串,等价于清除,keyboardOptions表示键盘return的图标,我们定义为ImeAction.Search,也就是搜索;keyboardActions表示点击return执行的方法,我们直接调用onSearch(),如图:
红色的x就是trailingIcon指定的,搜索就是keyboardOptions指定的。
2 实现下方列表
@Composable
fun ContentList(contentData: ContentsListData) {
val contents by contentData.getDisplayData().observeAsState(listOf())
LazyColumn(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.Start) {
items(contents) { content ->
Text(text = content, modifier = Modifier.padding(4.dp))
}
}
}
复制代码
函数接收一个LiveData;其中LazyColumn可以理解为Compose中的RecyclerView,items是内部的一个lambda,表示将contents这个list展开,然后去构造Text,contents的size是多少,就会构造多少个Text。
3 组合UI
@Composable
fun HomeScreen() {
Column {
SearchBar { keyword ->
Toast.makeText(this@MainActivity, “keyword is $keyword”, Toast.LENGTH_SHORT).show()
viewModel.filter(keyword = keyword)
}
Spacer(modifier = Modifier.size(8.dp))
ContentList(contentData = viewModel)
}
}
复制代码
Column等价于LinearLayout,Spacer等价于一个空白View,用来作为分割线。
建议
当我们出去找工作,或者准备找工作的时候,我们一定要想,我面试的目标是什么,我自己的技术栈有哪些,近期能掌握的有哪些,我的哪些短板 ,列出来,有计划的去完成,别看前两天掘金一些大佬在驳来驳去 ,他们的观点是他们的,不要因为他们的观点,膨胀了自己,影响自己的学习节奏。基础很大程度决定你自己技术层次的厚度,你再熟练框架也好,也会比你便宜的,性价比高的替代,很现实的问题但也要有危机意识,当我们年级大了,有哪些亮点,与比我们经历更旺盛的年轻小工程师,竞争。
-
无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!!!!!!!
-
准备想说怎么样写简历,想象算了,我觉得,技术就是你最好的简历
-
我希望每一个努力生活的it工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。
-
有什么问题想交流,欢迎给我私信,欢迎评论
【附】相关架构及资料
资料领取
点击这里免费获取
内含往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术
%E4%BC%9A%E8%BF%99%E4%BA%9B%EF%BC%9F%E5%A6%82%E4%BD%95%E9%9D%A2%E8%AF%95%E6%8B%BF%E9%AB%98%E8%96%AA%EF%BC%81.md)**
内含往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术