戰(zhàn)路徑)
Android圓角與自定義繪制從clipPath到60fps的實(shí)戰(zhàn)路徑【免費(fèi)下載鏈接】awesome-android-uiA curated list of awesome Android UI/UX libraries項(xiàng)目地址: https://gitcode.com/gh_mirrors/aw/awesome-android-ui頭像在Figma里是正圓上線變成帶白邊的橢圓PM在群里你“晚上能修好嗎”這個(gè)Android圓角的坑你大概率會(huì)碰到。awesome-android-ui 收了一堆現(xiàn)成的圓角組件但選之前先搞懂圓角到底怎么畫出來的不然庫的API看不懂只能怪自己。原理速覽圓角到底是怎么畫出來的所有圓角的本質(zhì)都是“裁剪”區(qū)別只在裁剪發(fā)生在哪一層clipPathCanvas層裁剪。自己構(gòu)造 RoundRect 路徑canvas.clipPath(roundPath)之后畫的東西只會(huì)出現(xiàn)在路徑內(nèi)。完全可控代價(jià)是每幀都要自己維護(hù)路徑。BitmapShaderPaint層“上釉”。把位圖包成 shader 再畫形狀系統(tǒng)按像素采樣圖片圓角被預(yù)烘進(jìn)位圖滾動(dòng)時(shí)只是貼圖。ViewOutlineProviderView層打碼。只告訴框架“輪廓是這個(gè)形狀”裁剪、陰影它自己處理你連 onDraw 都不用進(jìn)API 21 順帶送陰影。上面這張是倉庫里的 Rotatable旋轉(zhuǎn)縮放全走 Canvas 變換——和圓角同一套“繪制層”思路你想露出什么先說清楚裁掉什么。選型決策表先定場景再看庫圓角選型不用背先看這張表需求場景推薦方案一句話理由性能代價(jià)靜態(tài)背景ShapeDrawablecorners 屬性一行XML搞定零列表里的圓角圖BitmapShader 預(yù)烘RoundedImageView烘進(jìn)位圖不逐幀計(jì)算一次性位圖解碼跨版本圓角卡片CardView / Outline框架統(tǒng)一管角和陰影輕微圖層開銷點(diǎn)擊半徑變化動(dòng)畫自定義View 逐幀Path唯一能逐幀改的辦法逐幀CPU建路徑異形裁剪clipPath Path全可控星形六邊形都行逐幀建路徑場景拆解場景A列表圓角圖片不掉幀的寫法問題一百條的 feed每格一張 96dp 圖逐幀 clipPath手指一劃40fps。解法別逐幀算預(yù)烘。RoundedImageView 把 BitmapShader 那套封裝好了直接抄作業(yè)com.makeramen.roundedimageview.RoundedImageView android:layout_width96dp android:layout_height96dp app:riv_corner_radius12dp app:riv_border_width1dp app:riv_border_colorcolor/white android:srcdrawable/avatar/列表的寫法關(guān)鍵其實(shí)在圖片裝載鏈路。像 Kiel 這種聲明式適配器下圖一行數(shù)據(jù)一行圖圓角只是鏈路最后那 12dp。為什么這么選否決了逐幀 clipPath每幀新路徑CPU 不給力和逐格 ShapeDrawableDrawable 不緩存位圖布局一變就算一遍。烘成位圖之后滾動(dòng)就是貼圖60fps 穩(wěn)。場景B帶陰影圓角卡片的跨版本一致性問題同一張卡片5.0 上圓角干凈陰影柔和4.4 上角被切方、陰影發(fā)虛。用戶不管你的 minSdk只管設(shè)計(jì)裂沒裂。解法角和陰影一起交給框架別自己拼android.support.v7.widget.CardView android:layout_widthmatch_parent android:layout_heightwrap_content app:cardCornerRadius12dp app:cardElevation4dp app:cardPreventCornerOverlaptrue !-- 卡片內(nèi)容 -- /android.support.v7.widget.CardViewAPI 21 它內(nèi)部走 Outline陰影由框架畫老版本 CardView 會(huì)自己退化成位圖陰影。同一份布局角是同一個(gè)角。為什么這么選否決了 9-patch 陰影手搓每種密度畫一張遲早漏一張和純靠系統(tǒng) elevation5.0 以下沒陰影裸奔。場景C點(diǎn)擊時(shí)圓角半徑變化的交互動(dòng)畫問題關(guān)注按鈕要從 12dp 膠囊形點(diǎn)擊時(shí)長成全圓進(jìn)度環(huán)。兩個(gè)靜態(tài) Drawable 來回切是切不出過渡的——半徑本身得是個(gè)會(huì)動(dòng)的值。解法把圓角半徑變成可動(dòng)畫值逐幀重建 PathValueAnimator anim ValueAnimator.ofFloat(12f, getHeight() / 2f); anim.addUpdateListener(v - { cornerRadius (Float) v.getAnimatedValue(); invalidate(); // onDraw 里用新半徑重建 RoundRect }); anim.setDuration(180); anim.start();單按鈕、180ms、幾幀 CPU 建路徑無傷大雅。為什么這么選否決 Lottie——它是預(yù)制的矢量動(dòng)畫下圖順滑但半徑?jīng)]法跟業(yè)務(wù)狀態(tài)成功/失敗動(dòng)態(tài)走也否決 9-patch 切換瞬間跳變沒有過渡感。性能暗礁?? 三塊礁石踩得最多。逐幀建Path→ onDraw 里每幀path.addRoundRect(...)→ 列表滾動(dòng)每幀16msCPU先扛幀率先掉。硬件加速Xfermode→ Manifest 里android:hardwareAcceleratedfalse→ 硬件加速一關(guān)文字渲染全走CPU老機(jī)型直接卡。要用 Xfermode 就得認(rèn)這筆賬。嵌套布局做陰影→ CardView 外面再套一層 FrameLayout 畫陰影 → 多一層就多一層過度繪制列表滾動(dòng)時(shí) GPU 翻倍。圓角組件生態(tài)速查分三組對(duì)號(hào)入座圖片圓角CircleImageView — 圓形頭像最小實(shí)現(xiàn)開銷幾個(gè)KBRoundedImageView — 四角半徑可獨(dú)立設(shè)列表格子主力SelectableRoundedImageView — 帶選中態(tài)的版本適合可勾選列表容器圓角CardView — 官方圓角陰影容器跨版本最穩(wěn)Maskable Layout — 任意Path裁剪子控件clipPath 的容器版MaterialShadows — 跨版本一致的陰影配圓角卡片用異形裁剪ShapeImageView — 圖片裁成任意形狀圓形星形一把梭android-anyshape — 六邊形等多邊形幾何老師版異形RoundedLetterView — 圓角字母頭像沒圖時(shí)的兜底完整清單在倉庫 README.md選庫前先翻近6個(gè)月有沒有 commit三年沒動(dòng)的庫圓角雖然不會(huì)壞依賴遲早壞別賭。倉庫可直接克隆git clone https://gitcode.com/gh_mirrors/aw/awesome-android-ui一句話帶走把你項(xiàng)目里第一個(gè) ImageView 換成 RoundedImageView滑一下列表感受差距?!久赓M(fèi)下載鏈接】awesome-android-uiA curated list of awesome Android UI/UX libraries項(xiàng)目地址: https://gitcode.com/gh_mirrors/aw/awesome-android-ui創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考