成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

深入解析Android的自定義布局

移動(dòng)開發(fā) Android
這篇文章是前Firefox Android工程師(現(xiàn)在跳槽去Facebook了) Lucas Rocha所寫,文中對(duì)Android中常用的四種自定義布局方案進(jìn)行了很好地分析,并結(jié)合這四種Android自定義布局方案所寫的示例項(xiàng)目講解了它們各自的優(yōu)劣以及四種方案之間的比較。

[[124174]]

寫在前面的話:

這篇文章是前Firefox Android工程師(現(xiàn)在跳槽去Facebook了) Lucas Rocha所寫,文中對(duì)Android中常用的四種自定義布局方案進(jìn)行了很好地分析,并結(jié)合這四種Android自定義布局方案所寫的示例項(xiàng)目講解了它們各自的優(yōu)劣以及四種方案之間的比較。看完這篇文章,也讓我對(duì)Android 自定義布局有了進(jìn)一步的了解,于是趁著興頭,我把它翻譯成中文,原文鏈接在此

只要你寫過Android程序,你肯定使用過Android平臺(tái)內(nèi)建的幾個(gè)布局——RelativeLayout, LinearLayout, FrameLayout等等。 它們能幫助我們很好的構(gòu)建Android UI。

這些內(nèi)建的布局已經(jīng)提供了很多方便的構(gòu)件,但很多情況下你還是需要來定制自己的布局。

總結(jié)起來,自定義布局有兩大優(yōu)點(diǎn):

  1. 通過減少view的使用和更快地遍歷布局元素讓你的UI顯示更加有效率;
  2. 可以構(gòu)建那些無法由已有的view實(shí)現(xiàn)的UI。

在這篇博文中,我將實(shí)現(xiàn)四種不同的自定義布局,并對(duì)它們的優(yōu)缺點(diǎn)進(jìn)行比較。它們分別是: composite view, custom composite view, flat custom view, 和 async custom views。

這些代碼實(shí)現(xiàn)可以在我的github上的 android-layout-samples 項(xiàng)目里找到。這個(gè)app使用上面說到的四種自定義布局實(shí)現(xiàn)了相同的UI效果。它們使用 Picasso 來加載圖片。這個(gè)app的UI只是twitter timeline的簡(jiǎn)化版本——沒有交互,只有布局。

好啦,我們先從最常見的自定義布局開始吧: composite view。

Composite View

Composite views (也被稱為 compound views) 是眾多將多個(gè)view結(jié)合成為一個(gè)可重用UI組件的方法中最簡(jiǎn)單的。這種方法的實(shí)現(xiàn)過程是這樣的:

  1. 繼承相關(guān)的內(nèi)建的布局。
  2. 在構(gòu)造函數(shù)里面填充一個(gè) merge 布局。
  3. 初始化成員變量并通過 findViewById()指向內(nèi)部view。
  4. 添加自定義的API來查詢和更新view的狀態(tài)。

TweetCompositeViewcode 就是一個(gè) composite view。它繼承于 RelativeLayout,并填充了 tweet_composite_layout.xmlcode 布局文件,***向外界暴露了 update()方法來更新它在adaptercode里面的狀態(tài)。

Custom Composite View

上面提到的TweetCompositeView 這種實(shí)現(xiàn)方式能滿足大部分的情況。但是碰到某些情況就不靈了。假設(shè)你現(xiàn)在想要減少子視圖的數(shù)量,讓布局元素的便利更加有效。

這個(gè)時(shí)候我們可以回過頭來看看,盡管 composite views 實(shí)現(xiàn)起來比較簡(jiǎn)單,但是使用這些內(nèi)建的布局還是有不少的開銷的——特別是 LinearLayout 和RelativeLayout這種比較復(fù)雜的容器。由于Android平臺(tái)內(nèi)建布局的實(shí)現(xiàn),在一次布局元素遍歷中,系統(tǒng)需要處理許多布局的結(jié)合和子視圖的多次測(cè)量——LinearLayout的 layout_weight 的屬性就是常見例子。

因此你可以為你的app量身定做一套子視圖的計(jì)算和定位邏輯,這樣的話你就可以極大的優(yōu)化你的UI了。這種做法就是我接下來要介紹的 custom composite view.

顧名思義,一個(gè) custom composite view 就是一個(gè)重寫了onMeasure() 和onLayout() 方法的 composite view 。因此相比之前的composite view繼承了 RelativeLayout,現(xiàn)在我們需要更進(jìn)一步——繼承更抽象的ViewGroup。

TweetLayoutViewcode 就是通過這種技術(shù)實(shí)現(xiàn)的。注意現(xiàn)在這個(gè)實(shí)現(xiàn)不像 TweetComposiveView 繼承了LinearLayout ,這也就避免了 layout_weightcode這個(gè)屬性的使用了。

這個(gè)大費(fèi)周折的過程通過ViewGroup’s 的measureChildWithMargins() 方法和背后的 getChildMeasureSpec() 方法計(jì)算出了每個(gè)子視圖的 MeasureSpec 。

TweetLayoutView 不能正確地處理所有可能的 layout 組合但是它也不必這樣。我們肯定需要根據(jù)特定需求來優(yōu)化我們的自定義布局,這種方式可以讓我們寫出簡(jiǎn)單高效的布局代碼。

Flat Custom View

如你所見,custom composite views 可以簡(jiǎn)單地通過使用ViewGroup 的API就可以實(shí)現(xiàn)了。大部分時(shí)候,這種實(shí)現(xiàn)是可以滿足我們的需求的。

然而我們想更進(jìn)一步的話——優(yōu)化我們應(yīng)用中的關(guān)鍵部分UI,比如 ListViews ,ViewPager等等。如果我們把所有的 TweetLayoutView 子視圖合并成一個(gè)單一的自定義視圖然后統(tǒng)一管理會(huì)怎么樣呢?這就是我們接下來要討論的 flat custom view——參看下面的圖片。

layouts

左邊為CUSTOM COMPOSITE VIEW ,右邊是FLAT CUSTOM VIEW

flat custom view 就是一個(gè)完全自定義的 view ,它完全負(fù)責(zé)內(nèi)部的子視圖的計(jì)算,位置安排,繪制。所以它就直接繼承了View 而不是 ViewGroup。

如果你想找找現(xiàn)實(shí)生活中app是否存在這樣的例子,很簡(jiǎn)單——開啟你手機(jī)“開發(fā)者模式”里面的 “顯示布局邊界”選項(xiàng),然后打開 Twitter, Gmail, 或者 Pocket這些app,它們?cè)诹斜鞺I里面都采用了 flat custom view。

使用 flat custom view最主要的好處就是可以極大地壓縮app 的視圖層級(jí),進(jìn)而可以進(jìn)行更快的布局元素遍歷,最終可以減少內(nèi)存占用。

Flat custom view 可以給你***的自由,就好像你在一張白紙上面作畫。但是這樣的自由是有代價(jià)的:你不能使用已有的那些視圖元素了,比如 TextView 和 ImageView。沒錯(cuò),在 Canvas 上面描繪文本 的確很簡(jiǎn)單,但要你實(shí)現(xiàn) ellipsizing(就是對(duì)過長(zhǎng)的文本截?cái)啵┠兀客瑯樱?nbsp;在 Canvas 上面 描繪圖片確很簡(jiǎn)單,但是如何縮放呢?這些限制同樣適用于touch events, accessibility, keyboard navigation等等。

所以使用flat custom view的底線就是:只將flat custom view應(yīng)用于你的app的UI核心部分,其他的就直接依賴Android平臺(tái)提供的view了。

TweetElementViewcode 就是 flat custom view。為了更容易的實(shí)現(xiàn)它,我創(chuàng)建了一個(gè)小小的自定義視圖框架叫做UIElement。你可以在  canvascode 這個(gè)包里找到它。

UIElement 提供了和Android平臺(tái)類似的 measure/layout API 。它包含了沒有圖像界面的 TextView 和 ImageView ,這兩個(gè)元素包含了幾個(gè)必需的特性——分別參看 TextElementcode 和ImageElementcode 。它還擁有自己的 inflatercode ,幫助從 布局資源文件code里面實(shí)例化UIElement  。

注意: UIElement 還處于非常早期的開發(fā)階段,所以還有很多缺陷,不過將來隨著不斷的改進(jìn)UIElement 可能會(huì)變得非常有用。

你可能覺得TweetElementView 的代碼看起來很簡(jiǎn)單,這是因?yàn)閷?shí)際代碼都在 TweetElementcode里面——實(shí)際上TweetElementView 扮演托管的角色code

TweetElement  里面的布局代碼和TweetLayoutView‘非常類似,但是它使用 Picasso 請(qǐng)求圖片時(shí)卻不一樣code ,因?yàn)門weetElement  沒有使用ImageView。

Async Custom View

總所周知,Android UI 框架時(shí)單線程的 。 這樣的單線程會(huì)帶來一些限制。比如,你不能在主線程之外遍歷布局元素——然而這對(duì)復(fù)雜、動(dòng)態(tài)的UI是很有益處的。

假如你的app 在一個(gè)ListView 中很布局比較復(fù)雜的條目(就像大多數(shù)社交app一樣),那么你在滑動(dòng)ListView 就很有可能出現(xiàn)跳幀的現(xiàn)象,因?yàn)長(zhǎng)istView 需要為列表中即將出現(xiàn)的新內(nèi)容計(jì)算它們的視圖大小code和布局code。同樣的問題也會(huì)出現(xiàn)在GridViews,ViewPagers等等。

如果我們可以在主線程之外的線程上面對(duì)那些還沒有出現(xiàn)的子視圖進(jìn)行布局遍歷是不是就可以解決上面的問題了?也就是說,在子視圖上面調(diào)用 measure() 和layout() 方法都不會(huì)占用主線程的時(shí)間了。

所以 async custom view 就是一個(gè)允許子視圖布局遍歷過程發(fā)生在主線程之外的實(shí)驗(yàn),這個(gè)idea是受到Facebook的Paperteam async node framework 這個(gè)視頻激發(fā)所想到的。

既然我們?cè)谥骶€程之外永遠(yuǎn)接觸不到Android平臺(tái)的UI組件,因此我們需要一個(gè)API在不能直接接觸到這個(gè)視圖的前提下對(duì)這個(gè)視圖的內(nèi)容進(jìn)行測(cè)量、布局。這恰恰就是 UIElement 框架提供給我的功能。

AsyncTweetViewcode 就是一個(gè) async custom view。它使用了一個(gè)線程安全的 AsyncTweetElementcode 工廠類code 來定義它的內(nèi)容。具體過程是一個(gè) Smoothie 子項(xiàng)加載器code 在一個(gè)后臺(tái)線程上對(duì)暫時(shí)不可見的AsyncTweetElement 進(jìn)行創(chuàng)建、預(yù)測(cè)量和緩存(在內(nèi)存里面,以便后來直接使用)。

當(dāng)然在實(shí)現(xiàn)這個(gè)異步UI的過程中我還是妥協(xié)了一些,因?yàn)槟悴恢廊绾物@示任意高度的布局占位符。比如,當(dāng)布局異步傳遞過來的時(shí)候你只能在后臺(tái)線程對(duì)它們的大小進(jìn)行一次更改。因此當(dāng)一個(gè) AsyncTweetView 就要顯示的時(shí)候卻無法在內(nèi)存里面找到合適的AsyncTweetElement ,這個(gè)時(shí)候框架就會(huì)強(qiáng)制在主線程上面創(chuàng)建一個(gè)AsyncTweetElement code。

還有,預(yù)先加載的邏輯和內(nèi)存緩存過期時(shí)間設(shè)置都需要比較好的實(shí)現(xiàn)來保證在主線程盡可能多地利用內(nèi)存里面的緩存布局。比如,這個(gè)方案中使用 LRU 緩存code 就不是一個(gè)明智的選擇。

盡管還存在這些限制,但是使用 async custom view 的得到的初步結(jié)果還是很有前途的。當(dāng)然我也會(huì)通過重構(gòu)這個(gè)UIElement  框架和使用其他類別的UI在這個(gè)領(lǐng)域繼續(xù)探索。讓我們靜觀其變吧。

總結(jié)

在我們涉及到布局的時(shí)候,我們自定義的越深,我們能從Android平臺(tái)所能獲得的依賴就越少。所以我們也要避免過早優(yōu)化,只在確實(shí)能實(shí)實(shí)在在改善app質(zhì)量和性能的區(qū)域進(jìn)行完全的布局自定義。

這不是一個(gè)非黑即白的決定。在使用平臺(tái)提供的UI元素和完全自定義的兩種極端之間還有很多方案——從簡(jiǎn)單的composite views 到復(fù)雜的 async views。實(shí)際項(xiàng)目中,你可能會(huì)結(jié)合文中的幾種方案寫出優(yōu)秀的app。

責(zé)任編輯:閆佳明 來源: greenrobot.me
相關(guān)推薦

2010-08-11 09:01:41

Flex4布局

2016-11-16 21:55:55

源碼分析自定義view androi

2016-12-26 15:25:59

Android自定義View

2021-08-16 14:45:38

鴻蒙HarmonyOS應(yīng)用

2013-04-01 14:35:10

Android開發(fā)Android自定義x

2024-02-22 08:06:45

JSON策略解析器

2017-05-18 12:36:16

android萬能適配器列表視圖

2010-02-07 14:02:16

Android 界面

2025-01-10 09:28:25

2016-04-12 10:07:55

AndroidViewList

2017-05-19 10:03:31

AndroidBaseAdapter實(shí)踐

2011-04-27 10:31:38

Java

2012-12-24 14:42:48

iOS自定義狀態(tài)欄

2016-08-18 13:56:33

AndroidExecutorsubmit

2010-07-22 09:25:21

Symbian開發(fā)

2015-02-12 15:33:43

微信SDK

2018-07-06 15:58:34

SpringSchemaJava

2021-11-30 11:17:23

自定義配置插件

2015-01-14 15:06:48

定義相機(jī)

2013-05-02 14:08:18

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 黄色一级毛片免费看 | 欧美精品久久久久久久久老牛影院 | 亚洲视频一区 | 91视视频在线观看入口直接观看 | 一区二区三区不卡视频 | 九九综合九九 | 毛片一区二区 | 一区二区视频在线观看 | 91视频三区 | 九久久| 免费在线观看av的网站 | 国产一级淫片a直接免费看 免费a网站 | 欧美一级在线 | 久久久久久久久久久蜜桃 | 亚洲精品欧美 | 国产丝袜人妖cd露出 | 日韩精品一区二 | 久久新 | 亚洲啊v在线 | 亚洲精品久久嫩草网站秘色 | 91视频在线看| 国外成人在线视频 | 日本一区二区高清视频 | 亚洲成人一级片 | 午夜性视频 | 第四色狠狠 | 99精品视频免费观看 | 毛片网站在线观看视频 | 91视频在线 | 久草视频网站 | 一区二区三区视频在线观看 | 婷婷丁香综合网 | 日韩高清一区 | 欧美日韩淫片 | 久久精品综合网 | 天天干视频| 欧美精品一区二区三区在线 | 欧美日韩高清免费 | 久久久久久久久国产 | 在线免费观看毛片 | 中文字幕国产视频 |