最近一直在準(zhǔn)備軟考,天天在看教學(xué)視頻,這不后天就要考試了,我報的是軟件設(shè)計師,說說我對軟考的理解吧,軟考高級我不知道,就中級而言,非常符合中國的應(yīng)試性教育??嫉亩己軓V,但沒有一樣?xùn)|西考的精,我學(xué)了那么長時間,知識儲備已經(jīng)有了,考試應(yīng)付足夠了,但我覺得我可能永遠(yuǎn)沒有機(jī)會把這些只是應(yīng)用到實(shí)際中。扯多了,回歸正題。
我第一次聽說compose是在逛Android大牛講堂的時候,大佬說這會成為以后UI的主流框架,就很好奇到底是什么樣的東西能夠動搖xml那么多年的老大哥位置,還一直被谷歌力推,下面就讓我們來一步步走近它。
參看文章:Android開發(fā)者平臺
什么是compose
先看官方的解釋:
Jetpack Compose 是一個適用于 Android 的新式聲明性界面工具包。Compose 提供聲明性 API,讓您可在不以命令方式改變前端視圖的情況下呈現(xiàn)應(yīng)用界面,從而使編寫和維護(hù)應(yīng)用界面變得更加容易。此術(shù)語需要一些解釋說明,它的含義對應(yīng)用設(shè)計非常重要。
這里我就官方解釋給出自己的理解,不以命令方式改變前端視圖來呈現(xiàn)應(yīng)用界面,其實(shí)就是叫我們摒棄命令式UI,來使用Compose這種聲明式UI。那為什么要這樣做呢?
我們的傳統(tǒng)式UI在繪制界面上都是重新生成整個視圖,如果我們從服務(wù)器拿到一條數(shù)據(jù)需要適配給多個視圖,那更新起來會很麻煩,甚至出現(xiàn)忘記去更改數(shù)據(jù)的情況,Compose可以避免這種情況,當(dāng)然,這是后話了。還有一個原因是傳統(tǒng)命令式UI需要重新繪制視圖,從頭到尾重新渲染,這會導(dǎo)致消耗資源大,速度慢,而Compose做的只是在概念上從頭開始重新生成整個屏幕,實(shí)際上只執(zhí)行必要的更改。這就是他相比較于xml的優(yōu)勢所在。
compose的簡單使用
Compose的使用需要下載Android studio的Fox及以上版本,然后new一個compose的新工程,選擇Empty Compose Activity

基本代碼如下:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeDemo2Theme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
Greeting("Android")
}
}
}
}
}
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
ComposeDemo2Theme {
Greeting("Android")
}
}
我們可以看到很多不一樣的東西,首先看到兩個注解@compose和@Preview,@compose注解表示此注釋可告知 Compose 編譯器:此函數(shù)旨在將數(shù)據(jù)轉(zhuǎn)換為界面。也就是說帶有@conpose注解的函數(shù)都是編寫界面的函數(shù),通常我們叫它可組合函數(shù)。
對于@Preview注解看看官方的解釋:
Android Studio 允許您在 IDE 中預(yù)覽可組合函數(shù),無需將應(yīng)用安裝到 Android 設(shè)備或模擬器中??山M合函數(shù)必須為任何參數(shù)提供默認(rèn)值。因此,您無法直接預(yù)覽 MessageCard() 函數(shù),而是需要創(chuàng)建另一個名為 PreviewMessageCard() 的函數(shù),由該函數(shù)使用適當(dāng)?shù)膮?shù)調(diào)用 MessageCard()。請在 @Composable 上方添加 @Preview 注解。
就是@Preview注解的函數(shù)編寫的界面會展示在預(yù)覽區(qū)中。和實(shí)際效果不一定相同。
比如上述代碼改成
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeDemo2Theme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
Greeting("蒙奇.D.路飛")
}
}
}
}
}
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
ComposeDemo2Theme {
Greeting("Android")
}
}
我們可以看到在setContent中調(diào)用的和在預(yù)覽函數(shù)中調(diào)用的Greeting函數(shù)傳的參數(shù)不一樣,所以預(yù)覽視圖和實(shí)際運(yùn)行界面也不一樣
預(yù)覽視圖:

實(shí)際界面截圖:

那要怎么讓他們統(tǒng)一呢,很簡單,我們只需要在setContent里面也調(diào)用預(yù)覽函數(shù)就可以了,如下:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DefaultPreview()
}
}
}
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
ComposeDemo2Theme {
Greeting("蒙奇.D.路飛")
}
}
這樣預(yù)覽效果和實(shí)際效果就是一樣的了。
compose實(shí)現(xiàn)簡單布局
我們以官方給出的簡單demo為例:比如我們要創(chuàng)建這樣一個視圖:

首先在布局里面添加三個文本:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DefaultPreview()
}
}
}
@Composable
fun message(name: String, othername: String, phone: Long) {
Text(text = "綽號:$othername", fontSize = 14.sp)
Text(text = "電話號碼:$phone", fontSize = 14.sp)
Text(text = "姓名: $name!", fontSize = 14.sp)
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
ComposeDemoTheme {
message(name = "張志平", othername = "大帥比", phone = 110)
}
}
效果如圖所示:

我們會發(fā)現(xiàn)重疊在了一起,這時候使用Cloumn可以使他們豎直排序
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DefaultPreview()
}
}
}
@Composable
fun message(name: String, othername: String, phone: Long) {
Column {
Text(text = "綽號:$othername", fontSize = 14.sp)
Text(text = "電話號碼:$phone", fontSize = 14.sp)
Text(text = "姓名: $name!", fontSize = 14.sp)
}
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
ComposeDemoTheme {
message(name = "張志平", othername = "大帥比", phone = 110)
}
}
如圖:

接下來添加圖片,圖片與文字水平,使用Row
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DefaultPreview()
}
}
}
@Composable
fun message(name: String, othername: String, phone: Long) {
Column {
Text(text = "綽號:$othername", fontSize = 14.sp)
Text(text = "電話號碼:$phone", fontSize = 14.sp)
Text(text = "姓名: $name!", fontSize = 14.sp)
}
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
ComposeDemoTheme {
Row(modifier = Modifier.padding(all = 8.dp)) {
Image(
painter = painterResource(id = R.drawable.tx),
contentDescription = "聯(lián)系人照片",
modifier = Modifier
.size(60.dp)
.scale(1.0F),
contentScale = ContentScale.FillBounds
)
Spacer(modifier = Modifier.width(8.dp))
message(name = "張志平", othername = "大帥比", phone = 110)
}
}
}
圖片如圖所示:

到此,一個compose的簡單例子就完成了,可能里面有些方法和寫法大家會覺得很不熟悉,建議點(diǎn)進(jìn)去看一下源碼,我也是看著源碼寫的,源碼的注釋已經(jīng)很清楚了,不會看的兄弟們一定要學(xué)著去看,其實(shí)很簡單,不要自己把自己勸退,比如Image()里面的構(gòu)造參數(shù),怎么調(diào)大小,怎么調(diào)比例,都是在源碼里面可以找到的,后續(xù)我會逐漸深入地去了解它,也會寫出文章和大家交流。