《Jetpack Compose系列学习》-2 Compose编程思想

分析第一个程序

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeTheme {
                // A surface container using the 'background' color from the theme
                Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
                    Greeting("Android")
                }
            }
        }
    }
}
复制代码

我们可以看到,compose的入口还是Activity,但和之前不同的是,onCreate方法中的setContentView方法不见了,取而代之的是setContent。那么怎么显示布局呢?我们点到setContent的源码看看里面怎么做的:

public fun ComponentActivity.setContent(
    parent: CompositionContext? = null,
    content: @Composable () -> Unit
) {
    val existingComposeView = window.decorView
        .findViewById<ViewGroup>(android.R.id.content)
        .getChildAt(0) as? ComposeView

    if (existingComposeView != null) with(existingComposeView) {
        setParentCompositionContext(parent)
        setContent(content)
    } else ComposeView(this).apply {
        // Set content and parent **before** setContentView
        // to have ComposeView create the composition on attach
        setParentCompositionContext(parent)
        setContent(content)
        // Set the view tree owners before setting the content view so that the inflation process
        // and attach listeners will see them already present
        setOwners()
        setContentView(this, DefaultActivityContentLayoutParams)
    }
}
复制代码

首先这个方法是ComponentActivity的一个扩展方法,而上面自动生成的MainActivity也继承自ComponentActivity。下面通过Activity中window的decorView来找到根布局,再获取根布局的第0个子布局并将其强制转化为ComposeView。但现在我们并没有设置,所以existingComposeView为NULL,遇事会走进else分支创建一个新的ComposeView,然后在setContentView之前设置内容和父项,以使ComposeView创建合成,最后就会调用setContentView。在setContent方法中,第一个参数为Compose中的父控件,用于调度,第二个参数是一个含有Composable lambda参数的Composable函数。

setContent中包裹着ComposeTheme,他是Compose的主题,包裹着Surface并设定了页面的背景颜色,Surface中包裹着的Greeting就是显示在页面上的控件,即页面展示的Hellow World控件。

@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}
复制代码

Greeting是一个方法,也叫可组合函数,因为在Compose中可以使用的控件。使用Compose控件需要注意以下几点:

1.此函数带有@Composable注解。所有可组合函数都必须带有此注解,该注解告知Compose编 译器:这个函数旨在将数据转换成界面。

2.可组合函数可以接收参数,这些参数可以让应用程序逻辑描述页面,比如上面的例子中Greeing方法接收String类型的参数,可直接显示在界面中。

3.可组合函数没有返回值,发出界面的Compose函数不需要返回任何内容,

4.可组合函数在描述界面中的时候没有任何副作用,比如修改属性或全局变量等。

使用Preview

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    ComposeTheme {
        Greeting("Android")
    }
}
复制代码

我们在右侧的Split可以看到预览效果

image.png
试着把方法参数“Android”修改成“My Android”

image.png
如果修改代码后预览没有及时更新,则手动点击左上角的刷新按钮即可刷新。

Preview使用方法有很多,我们可以看看这个注解类的代码:

@Repeatable
annotation class Preview(
    val name: String = "",
    val group: String = "",
    @IntRange(from = 1) val apiLevel: Int = -1,
    // TODO(mount): Make this Dp when they are inline classes
    val widthDp: Int = -1,
    // TODO(mount): Make this Dp when they are inline classes
    val heightDp: Int = -1,
    val locale: String = "",
    @FloatRange(from = 0.01) val fontScale: Float = 1f,
    val showSystemUi: Boolean = false,
    val showBackground: Boolean = false,
    val backgroundColor: Long = 0,
    @UiMode val uiMode: Int = 0,
    @Device val device: String = Devices.DEFAULT
)
复制代码

我们试着更改预览态的宽高,我们可以在右侧预览态看到效果:

@Preview(showBackground = true, widthDp = 100, heightDp = 150)
@Composable
fun DefaultPreview() {
    ComposeTheme {
        Greeting("My Android")
    }
}
复制代码

image.png

image.png
其他的属性大家可以试着去验证下。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享