compose使用及優(yōu)缺點(diǎn)思考

相信大部分安卓開發(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)景有使用了冰蘑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市村缸,隨后出現(xiàn)的幾起案子祠肥,更是在濱河造成了極大的恐慌,老刑警劉巖梯皿,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仇箱,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡东羹,警方通過查閱死者的電腦和手機(jī)剂桥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來属提,“玉大人渊额,你說我怎么就攤上這事±萋#” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵火惊,是天一觀的道長(zhǎng)求类。 經(jīng)常有香客問我,道長(zhǎng)屹耐,這世上最難降的妖魔是什么尸疆? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮惶岭,結(jié)果婚禮上寿弱,老公的妹妹穿的比我還像新娘。我一直安慰自己按灶,他們只是感情好症革,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鸯旁,像睡著了一般噪矛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上铺罢,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天艇挨,我揣著相機(jī)與錄音,去河邊找鬼韭赘。 笑死缩滨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播脉漏,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼苞冯,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了鸠删?” 一聲冷哼從身側(cè)響起抱完,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刃泡,沒想到半個(gè)月后巧娱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烘贴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年禁添,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桨踪。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡老翘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锻离,到底是詐尸還是另有隱情铺峭,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布汽纠,位于F島的核電站卫键,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏虱朵。R本人自食惡果不足惜莉炉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望碴犬。 院中可真熱鬧絮宁,春花似錦、人聲如沸服协。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽偿荷。三九已至治专,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間遭顶,已是汗流浹背张峰。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棒旗,地道東北人喘批。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓撩荣,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親饶深。 傳聞我的和親對(duì)象是個(gè)殘疾皇子餐曹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353