他是什么
Jetpack Compose 是用于構(gòu)建原生 Android 界面的新工具包。它使用更少的代碼、強(qiáng)大的工具和直觀的 Kotlin API,可以幫助您簡(jiǎn)化并加快 Android 界面開(kāi)發(fā),打造生動(dòng)而精彩的應(yīng)用。
缺點(diǎn)
包體積增大, aab 集成compose之前:266451kb downloadsize 256.8MB
272052kb 262.2mb。為其支持的第三方庫(kù)少
優(yōu)勢(shì)
減少耦合 增加內(nèi)聚, 用更少的代碼實(shí)現(xiàn)功能。編寫(xiě)代碼只需要采用 Kotlin,而不必拆分成 Kotlin 和 XML 部分。
在 Compose 中,狀態(tài)是顯式的,并且會(huì)傳遞給相應(yīng)的可組合項(xiàng)。這樣一來(lái),狀態(tài)便具有單一可信來(lái)源。
Compose 使用聲明性 API,這意味著您只需描述界面,Compose 會(huì)負(fù)責(zé)完成其余工作。這類 API 十分直觀 。
聲明式UI 相對(duì)于命令式UI 更加直觀和邏輯清晰。您可以構(gòu)建不與特定 activity 或 fragment 相關(guān)聯(lián)的小型無(wú)狀態(tài)組件。(比如實(shí)現(xiàn)recylerView ),
recyclerView 在布局加入
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:id="@+id/recycler_view"
android:layout_height="wrap_content" />
對(duì)應(yīng)的item 布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center"
android:textColor="@color/red"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
初始化 recyclerView
mbinding.recyclerView.apply {
layoutManager=LinearLayoutManager(this@TestActivity)
adapter=TestAdapter(mutableListOf("test--->","test1--->", "test2--->"))
}
對(duì)應(yīng)的Adapter
class TestAdapter(val mData: MutableList<String>) :
RecyclerView.Adapter<TestAdapter.TestViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TestViewHolder {
ItemTestAdapterItemBinding.inflate(LayoutInflater.from(parent.context)).apply {
return TestViewHolder(this)
}
}
override fun getItemCount(): Int {
return mData.size
}
override fun onBindViewHolder(holder: TestViewHolder, position: Int) {
val data = mData.get(position)
holder.bindData(data)
}
inner class TestViewHolder(val itemBinding: ItemTestAdapterItemBinding) :
RecyclerView.ViewHolder(itemBinding.root) {
fun bindData(data: String) {
itemBinding.textView.text = data
}
}
}
compose 實(shí)現(xiàn)
@Composable
fun testRecyclerView() {
val list = listOf("a", "b", "c")
LazyColumn {
items(list) {
Text(text = it, color = Color.Red,modifier = Modifier.fillMaxSize())
}
}
}
和當(dāng)前View 體系的平替關(guān)系
布局:
RecyclerView ->LazyColum/LazyRow/LazyVerticalGrid/LazyHorizontalGrid/LazyVerticalStaggeredGrid /LazyHorizontalStaggeredGrid
LinearLayout->Row/Colum
FramLayout->Box
ViewPager->HorizontalPager/VerticalPager
FlowLayout(非官方)->FlowRow /FlowColumn
ConstraintLayout->ConstraintLayout
控件
TextView ->Text
EditTextView->TextField/OutlinedTextField
ImageView->Image/Icon/GlideImage(網(wǎng)絡(luò)圖)/AsyncImage(Coil網(wǎng)絡(luò)圖)
Button->Button/TextButton/ElevatedButton/OutlinedButton/FilledTonalButton
FloatingActionButton->FloatingActionButton/SmallFloatingActionButton/LargeFloatingActionButton/ExtendedFloatingActionButton
ProgressBar->LinearProgressIndicator /CircularProgressIndicator
SeekBar->Slider
修飾符
借助修飾符,您可以修飾或擴(kuò)充可組合項(xiàng)。您可以使用修飾符來(lái)執(zhí)行以下操作:
更改可組合項(xiàng)的大小、布局、行為和外觀
添加信息,如無(wú)障礙標(biāo)簽
處理用戶輸入
添加高級(jí)互動(dòng),如使元素可點(diǎn)擊、可滾動(dòng)、可拖動(dòng)或可縮放
修飾符是標(biāo)準(zhǔn)的 Kotlin 對(duì)象。您可以通過(guò)調(diào)用某個(gè) Modifier類函數(shù)來(lái)創(chuàng)建修飾符:
常見(jiàn)的align,border,alpha,background,clip,padding,size,clickable等
修飾符順序影響:

Modifier
.clickable(onClick = onClick)
.padding(padding)
.fillMaxWidth()
Modifier
.padding(padding)
.clickable(onClick = onClick)
.fillMaxWidth()

更多。。https://developer.android.google.cn/develop/ui/compose/modifiers?hl=zh-cn
繪制不規(guī)則背景

Box(
Modifier
.drawBehind {
Path().apply {
val lineSize=15.dp()
moveTo(size.width/8f,size.height-2.dp())
lineTo(size.width/8f+lineSize/2,size.height+lineSize/2-2.dp())
lineTo(size.width/8f+lineSize,size.height-2.dp())
close()
drawPath(path = this, color = color_fotor_blue)
}
}
.clip(RoundedCornerShape(8.dp))
.background(color_fotor_blue)
.padding(horizontal = 8.dp, vertical = 2.dp)
) {
Text("請(qǐng)先閱讀并同意后登錄", color = white, fontSize = 11.sp)
}
重組觸發(fā)順序如下:
重組
智能重組:每當(dāng)狀態(tài)更新時(shí),都會(huì)發(fā)生重組重組通常由對(duì) State<T> 對(duì)象的更改觸發(fā)
通過(guò)remember 關(guān)鍵字 創(chuàng)建MutableState<T> ,對(duì)MutableState的 value 所做的任何更改都會(huì)安排對(duì)讀取 value 的所有可組合函數(shù)進(jìn)行重組。
首先攜帶狀態(tài)數(shù)據(jù)觸發(fā)重組的View >> Compose的其他View重組 >> DisposableEffect >> SideEffect >> LaunchedEffect
Compose和View體系互相調(diào)用
在xml 種使用composeview
<androidx.compose.ui.platform.ComposeView
android:id="@+id/compose_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
在代碼種對(duì)他調(diào)用
setContent {
// 需要使用的compose 組件
}
在compose 中使用xml
AndroidView(factory = {
val view = LayoutInflater.from(it).inflate(R.layout.xxx, null)
view
}, modifier = Modifier.fillMaxSize())
Compose 中的附帶效應(yīng)
附帶效應(yīng)是指發(fā)生在可組合作用域之外的應(yīng)用狀態(tài)的變化,可組合項(xiàng)在理想情況下應(yīng)該是無(wú)附帶效應(yīng)的,不過(guò),有時(shí)附帶效應(yīng)是必要的,例如,觸發(fā)一次性事件(例如顯示信息提示控件),或在滿足特定狀態(tài)條件時(shí)進(jìn)入另一個(gè)屏幕。
LaunchedEffect可以傳遞一個(gè)參數(shù)key,如果key發(fā)生變化,系統(tǒng)將取消現(xiàn)有協(xié)程,并在新的協(xié)程中啟動(dòng)新的掛起函數(shù)。
rememberCoroutineScope:獲取組合感知作用域,以在可組合項(xiàng)外啟動(dòng)協(xié)程,比如onClick 代碼塊
rememberUpdatedState:在效應(yīng)中引用值,該值在值發(fā)生更改時(shí)不應(yīng)重啟
DisposableEffect:需要清理的效果
SideEffect :使用 SideEffect 可確保在每次成功重組后執(zhí)行該效果。
produceState:使用此協(xié)程將非 Compose 狀態(tài)轉(zhuǎn)換為 Compose 狀態(tài),例如將外部訂閱驅(qū)動(dòng)的狀態(tài)(如 Flow、LiveData 或 RxJava)引入組合。
snapshotFlow:使用 [snapshotFlow] 將[State<T>] 對(duì)象轉(zhuǎn)換為冷 Flow。
derivedStateOf:當(dāng)可組合項(xiàng)輸入的變化頻率超過(guò)您需要的重組頻率時(shí),就應(yīng)該使用 derivedStateOf 函數(shù)。這種情況通常是指,某些內(nèi)容(例如滾動(dòng)位置)頻繁變化,但可組合項(xiàng)只有在超過(guò)某個(gè)閾值時(shí)才需要對(duì)其做出響應(yīng)。
val showButton by remember {
derivedStateOf {
listState.firstVisibleItemIndex > 0
}
}