相信大部分安卓開發(fā)都經(jīng)常聽到compose旭等,真正項(xiàng)目中使用的還是比較少。最近剛好看了下2年前的compose學(xué)習(xí)時(shí)demo秸妥,也簡(jiǎn)單的介紹下我理解的compose
簡(jiǎn)單使用
compose是組合式的UI框架焰宣,在fragment中使用如下:
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
load()
return ComposeView(requireContext()).apply {
setContent {
val listState = rememberLazyListState()
LazyColumn(
contentPadding = PaddingValues(
start = 16.dp,
end = 16.dp,
bottom = 10.dp,
top = 10.dp
),
state = listState
) {
items(contentlist) {
setSection(it)
}
}
LoadMoreListHandler(listState = listState) {
load()
}
}
}
}
其中填充item的代碼
@Composable
fun setSection(item: TitleComposableModel) {
Box(modifier = Modifier) {
Text(
text = item.title,
color = Color.Black,
fontSize = 25.sp,
modifier = Modifier.align(Alignment.BottomStart).padding(15.dp)
)
}
val pxValue = with(LocalDensity.current) { 1.dp.toPx() }
Spacer(
Modifier
.background(Color.Gray)
.fillMaxWidth()
.height((1/pxValue).dp)
)
}
簡(jiǎn)單解釋下,compose直接返回的是ComposeView
, 調(diào)用setContent傳入一個(gè)@composeble的對(duì)象谭溉,替代原來的 setContentView(layout), LazyColumn
就是替換recycleView的墙懂,回想之前使用recycleView時(shí),借用kotlin的語法也要寫一堆代碼扮念,不同type時(shí)候還要寫多個(gè)if else 在compose 組件里面就這樣就實(shí)現(xiàn)了(if else也能通過SPI:service provider interface 技術(shù)優(yōu)化掉, 保證開閉原則)损搬,每個(gè)item的填充直接把屬性寫到compose控件上
這跟flutter使用dart的寫法差不多啊,也和前端的開發(fā)差不多柜与!
甚至連腳手架Scaffold
都直接搬過來了巧勤!??
@ExperimentalMaterialApi
@ExperimentalPagerApi
@Composable
fun MainScreen() {
val navController = rememberNavController()
Scaffold(
topBar = { TopBar() },
bottomBar = { BottomNavigationBar(navController) }
) {
Navigation(navController = navController)
}
}
compose原理
數(shù)據(jù)驅(qū)動(dòng) 根據(jù)接口數(shù)據(jù)轉(zhuǎn)換為對(duì)應(yīng)model刷新UI
compose為啥可以隨便嵌套不卡
傳統(tǒng)的布局
布局文件的界面層級(jí)要盡量地少,因?yàn)閷蛹?jí)的增加各種 Layout 的重復(fù)測(cè)量,會(huì)大幅拖慢界面的加載.
比如下面布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="48dp" />
<View
android:layout_width="120dp"
android:layout_height="48dp" />
<View
android:layout_width="320dp"
android:layout_height="48dp" />
<View
android:layout_width="match_parent"
android:layout_height="48dp" />
</LinearLayout>
LinearLayout 就會(huì)先以 0 為強(qiáng)制寬度測(cè)量matchparent的子 View,并正常地測(cè)量剩下的其他子 View弄匕,然后再用其他子 View 里最寬的那個(gè)的寬度颅悉,二次測(cè)量這些 match_parent 的子 View,最終得出它的尺寸迁匠,并把這個(gè)寬度作為自己最終的寬度剩瓶, 這也是我們自定義布局時(shí)候發(fā)現(xiàn)onMeasure為啥會(huì)執(zhí)行多次的原因
隨著層級(jí)的遞增,測(cè)量的次數(shù)會(huì)不斷快速增加城丧,
Compose 是禁止二次測(cè)量
Compose 禁用了二次測(cè)量延曙,但加入了一個(gè)新東西:Intrinsic Measurement 固有測(cè)量
Compose 允許父組件在對(duì)子組件進(jìn)行測(cè)量之前,先測(cè)量一下子組件的「固有尺寸」芙贫,簡(jiǎn)單地說就是「你內(nèi)部?jī)?nèi)容的最大或者最小尺寸是多少」搂鲫。這是一種粗略的測(cè)量,雖說沒有真正的「二次測(cè)量」模式那么自由磺平,但功能并不弱魂仍,因?yàn)楦鞣N Layout 里的重復(fù)測(cè)量拐辽,其實(shí)本來就是先進(jìn)行這種「粗略測(cè)量」再進(jìn)行最終的「正式測(cè)量」的
測(cè)量是很輕的,并不是因?yàn)樗康每觳磷茫且驗(yàn)樗跈C(jī)制上不會(huì)像傳統(tǒng)的二次測(cè)量那樣俱诸,讓組件的測(cè)量時(shí)間隨著層級(jí)的加深而不斷加倍
比如我們?cè)赾ompose里面嵌套5層box
按照傳統(tǒng)View的思維,當(dāng)前content(R.id.content(FrameLayout)->)布局中存在5層嵌套,這是極不可取的一種做法赊舶。但是現(xiàn)在是Compose睁搭,最終的繪制R.id.content 上掛載composeView,可以理解為支持compose的一個(gè)自定義view,上面再放了AndroidComposeView,再把compose的組件都渲染到這個(gè)view上笼平。 總共兩層园骆!
LayoutNodeWrapper鏈構(gòu)建
不同的text button都會(huì)轉(zhuǎn)換為L(zhǎng)ayoutNode,給Layout的設(shè)置的modifier會(huì)以LayoutNodeWrapper鏈的形式存儲(chǔ)在LayoutNode中寓调,然后后續(xù)做相應(yīng)變換
compose @composeable (組合視圖注解 compose平臺(tái)語言來處理更新) 反編譯修飾的方法還有個(gè)co mposer 參數(shù)到每個(gè)被注解修飾的方法上 composer composition 首次加載的view對(duì)象
compose總結(jié)
優(yōu)點(diǎn)
1.更簡(jiǎn)潔的代碼就能實(shí)現(xiàn)UI功能锌唾,不用再寫XML布局文件,不再采用傳統(tǒng)的繼承View/Viewgroup,畢竟View的代碼都3W多行 框架非常重夺英,也體現(xiàn)了"組合優(yōu)于繼承"晌涕。
2.對(duì)比傳統(tǒng)的布局文件,嵌套層級(jí)對(duì)性能影響大大減少痛悯。對(duì)于使用databingding項(xiàng)目代碼也不用布局里面去處理余黎,開發(fā)更高效
3.compose支持現(xiàn)有項(xiàng)目中混合使用,還能嵌套使用 甚至頁面一塊區(qū)域使用载萌。
缺點(diǎn)
1.API 熟悉還是有一定成本惧财,尤其是沒做過flutter、前端開發(fā)的同學(xué)
2.只能用在安卓端炒考,目前整體市面上商用的公司還不算多
3.圖片的支持不支持webp圖片
4.2024年使用AS的預(yù)覽功能 感覺比較卡 對(duì)比前端的Vue flutter熱更新還是差點(diǎn)
5.在傳統(tǒng)的 Android 開發(fā)中可缚,開發(fā)者可以通過重寫生命周期方法來管理界面的狀態(tài)要使用 Compose 提供的狀態(tài)管理機(jī)制來管理界面的狀態(tài)
是否要深入研究compose以及商用?
未來的趨勢(shì)大前端斋枢,所有端最好用一套代碼帘靡,現(xiàn)在市面已經(jīng)有很多了,uniapp,kuickly等等瓤帚。
要看公司實(shí)際需求和規(guī)劃描姚,如果公司歷史負(fù)債多,強(qiáng)行遷移成本會(huì)比較大戈次,如果是一些新的項(xiàng)目 組內(nèi)開發(fā)也都愿意轩勘,就可以使用。
商用與否怯邪,也得看實(shí)際情況绊寻,雖然compose確實(shí)在布局性能上有很大優(yōu)勢(shì),但是在一些求穩(wěn)的業(yè)務(wù)上,可以選一些邊緣的頁面混合使用澄步。比如我們?cè)趨^(qū)塊鏈的項(xiàng)目 關(guān)于部分和一些個(gè)人信息的場(chǎng)景有使用了冰蘑。