接上篇文章,打开默认工程后我们会看到一段Hello Android!默认代码。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
// A surface container using the 'background' color from the theme
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
Greeting("Android")
}
}
}
}
}
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
MyApplicationTheme {
Greeting("Android")
}
}
你会发现,DefaultPreview()和Greeting()前面都有个 @ Composable。这种函数名前面加上一个 @Composable 注解的函数叫做compose函数,Jetpack Compose就是围绕 composable 函数来构建的。
加@Compose注解的函数可以相互调用(使用@Composable注解修饰,表示这是一个可组合函数),这些函数会被插件编译处理,所以如果一个函数不是生成UI的,那么不要用此注解。@Preview注解,可以在右边实时预览(实时预览也是更新使用JetpackCompose后有的新特性),改动函数后,刷新一个预览即可,添加该注解的外层函数不能有参数,但是里面可以嵌套一个带参数的函数来预览。可以在@Preview后面添加一个名字,如:@Preview(“code preview”)。
此外,compose 的预览还可以同时预览多个 composable 函数,如下图:
setContent()是ComponentActivity的一个拓展方法,其中的content参数需要传入一个由@Composable注解的函数,值得一提的是@Composable并非传统意义上的注解处理器,Compose 在 Kotlin 编译器的类型检测与代码生成阶段依赖 Kotlin 编译器插件工作,所以无需注解处理器即可使用 Compose。
观察其源码,我们可以发现,程序逻辑会先去寻找Activity的根布局,若未找到则创建一个,然后将由@Conposable注解函数内的声明式布局创建。传入到setContent()中的Greeting()是创建的视图内容的具体声明描述罢了。
函数:Text()
Text("默认")
若只需要单纯的显示字符串,只需要将字符串放在Text()的括号里即可,同时也可以附上其他属性,中间用逗号隔开即可。
Text("大小、颜色", fontSize = 16.sp, color = Color.Blue)
Text("斜体", fontStyle = FontStyle.Italic , fontWeight = FontWeight.Bold)
Text("居中 字体Serif", textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth(), fontFamily = FontFamily.Serif)
Text("SansSerif字体文字溢出... ".repeat(50), maxLines = 2,
overflow = TextOverflow.Ellipsis, fontFamily = FontFamily.SansSerif)
将以上Text()放到@Preview函数里可以依次看到预览:
文字可选择:SelectionContainer(){}
文字不可选择:DisableSelection(){}
可点击文字:ClickableText(){}
组合文字:buildAnnotatedString(){}
…等等,结合在一起,可以组成各种想要的花式界面,例如:
Text(
buildAnnotatedString {
withStyle(style = SpanStyle(color = Color.Red)) {
append("H")
}
append("e")
withStyle(style = SpanStyle(color = Color.Yellow)){
append("ll")
}
append("o ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Blue)) {
append("And")
}
append("roid")
}
)
可预览显示出:
当我们要设置多个Text()时,如果你按下面方式设置,会显示如下预览界面:
上述代码由于我们还没有提供有关如何排列它们的任何信息,因此三个文本元素显示相互重叠绘制使得文本可读性极差。
这里就要引入我们的纵向布局Column () ,名字跟Flutter中的Column Weight的名字不能说很像,只能说一模一样,当然,功能也一样。效果如下图所示:
可见,Column()的加入使得前面重叠的Text垂直排列了,默认情况下从左上角开始往下依次排列,就像原生安卓的LinearLayout,当然,也可以进行一些样式更改。在调用Column()时传递参数来配置大小、位置以及排列方式。
Column (
Modifier.background(Color.Red)
.width(50.dp)
.height(90.dp),
horizontalAlignment = Alignment.CenterHorizontally,//子元素的水平方向对齐
verticalArrangement = Arrangement.Center//子元素的垂直方向对齐效果
){
Text(text = "11111")
Text(text = "22222")
Text(text = "33333")
}
此段代码运行后的效果则是:
Modifier.background(Color.Red).width(50.dp).height(90.dp)
这段代码声明了背景颜色及宽度和高度。此段代码等价于
Modifier.background(Color.Red).size(50.dp,90.dp)
(size、width、height在这不是必填选项,可只填背景也可只设置宽高)另外两个属性则代表意思是:
horizontalAlignment :子元素的水平方向对齐
verticalArrangement :子元素的垂直方向排列
(注意,你看上述运行效果就明白这里面的对齐排列指的是子元素Text相对于背景的属性,而不是整个屏幕)。
两个属性的取值如下表:
verticalArrangement = Arrangement.spacedBy(4.dp)
上述已经说明,Column()是将多个项垂直地放置在屏幕上。与此相对,使用横向布局 Row() 可将多个项水平地放置在屏幕上。Row()的属性名称跟Column()有些许差别外,其余差别不大,与之相对的属性:
horizontalArrangement :子元素的水平方向排列效果
verticalAlignmentment :子元素的垂直方向对齐效果
当然,也可以在调用的时候修改颜色、对其位置等属性:
Row (
Modifier.background(Color.Red)
.size(90.dp,50.dp),
horizontalArrangement = Arrangement.Center,//子元素的水平方向对齐
verticalAlignment = Alignment.CenterVertically//子元素的垂直方向对齐效果
){
Text(text = "111")
Text(text = "222")
Text(text = "333")
}
对应的效果为:
取值类型和设置边距(Row()为横向)也与Column()一致。
End,有问题请留言。