compose ui

他是什么

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等

修飾符順序影響:


layout-padding-clickable.gif
 Modifier
            .clickable(onClick = onClick)
            .padding(padding)
            .fillMaxWidth()
    Modifier
            .padding(padding)
            .clickable(onClick = onClick)
            .fillMaxWidth()
layout-padding-not-clickable.gif

更多。。https://developer.android.google.cn/develop/ui/compose/modifiers?hl=zh-cn

繪制不規(guī)則背景

image.png
      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
            }
        }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容