Litho學(xué)習(xí)之--列表的實(shí)現(xiàn)-1

這篇文章主要講解一個(gè)簡(jiǎn)單列表的實(shí)現(xiàn)费奸,包括如何自定義列表中的每個(gè)條目, 利用 RecyclerCollectionComponent 組件以及 Sections 庫(kù)來創(chuàng)建列表谢谦,如何自定義每個(gè)組件的屬性释牺。

第一個(gè)自定義組件

首先我們先來定義列表中的條目,每個(gè)條目包含一個(gè)主標(biāo)題和副標(biāo)題回挽,Litho 的預(yù)定義組件中并沒有這樣的組件没咙,事實(shí)上也不應(yīng)該有這樣的組件,需要我們自定義組件千劈,相當(dāng)于在 Android 系統(tǒng)中 LinearLayout 中的垂直方向擺放兩個(gè) TextView 祭刚。 Litho 中,編寫 Spec 類來聲明組件的布局墙牌,也就是編寫各種不同組件的組合涡驮,在 Spec 類上添加 @LayoutSpec 注解,編寫一個(gè)用 @OnCreateLayout 注解的方法返回需要顯示的組件喜滨,實(shí)際上用到的類是去掉 Spec 后綴的 Component 類捉捅,框架會(huì)生成代碼中真正用到的 Component 類,這里我們的自定義組件叫做 ListItem 虽风,相應(yīng)地棒口,我們要編寫 ListItemSpec 類:

@LayoutSpec
public class ListItemSpec {

  @OnCreateLayout
  static Component onCreateLayout(ComponentContext c) {

    return Column.create(c)
        .paddingDip(ALL, 16)
        .backgroundColor(Color.WHITE)
        .child(
            Text.create(c)
                .text("Hello world")
                .textSizeSp(40))
        .child(
            Text.create(c)
                .text("Litho tutorial")
                .textSizeSp(20))
        .build();
  }

}

解釋:

這里的 Text 就是 Hello World 里面見到的 Litho 中的核心組件,這個(gè)例子中辜膝,我們把 Text 組件作為 Column 的子組件傳入陌凳,這里的 Column 相當(dāng)于 Android 中垂直方向的 LinearLayout ,里面設(shè)置了 padding 和 backbroundColor 兩個(gè)屬性。

那么如何使用我們剛剛編寫的這個(gè)組件内舟?

final Component component = ListItem.create(context).build();

注意:這里我們用的是 ListItem,而不是 ListItemSpec初橘。

那么 ListItem 是怎么來的验游? create() 和 build() 方法在哪里定義的充岛?
在 Hello World 中我們?cè)?gradle 文件中添加入了有關(guān)注解處理器的依賴, Litho 的注解處理器會(huì)掃描代碼耕蝉,查找 Spec 類崔梗,并生成去掉后綴 Spec 的組件類,同時(shí)自動(dòng)填充一些必要的方法垒在。

Litho 還可以實(shí)現(xiàn)類似于 LinearLayout 中的 weight 和 FrameLayout 的效果蒜魄,請(qǐng)參考 Layout

運(yùn)行APP场躯,效果如下:

First Custom Component

創(chuàng)建列表

這一節(jié)我們要使用到 Litho 中的 RecyclerCollectionComponent 組件以及 Sections 庫(kù)來創(chuàng)建列表谈为。
RecyclerCollectionComponent 用于創(chuàng)建 Litho 滾動(dòng)的單元,隱藏了直接使用 Android 中 RecyclerView 和 Adapter 交互的復(fù)雜性踢关。
Sections API 可以把列表中的條目放到 Section 中伞鲫,寫 GroupSectionSpec 類來聲明每個(gè) Section 要渲染的內(nèi)容和使用的數(shù)據(jù)。
這里我們要自定義的 Section 叫做 ListSection, 因此需要聲明 ListSectionSpec 類签舞,在類上添加 @GroupSectionSpec 注解秕脓,定義 onCreateChildren 方法,返回需要渲染的子 Section 們儒搭,這里每個(gè)子 Section 顯示一個(gè) ListItem 組件吠架。

@GroupSectionSpec
public class ListSectionSpec {

  @OnCreateChildren
  static Children onCreateChildren(final SectionContext c) {
    Children.Builder builder = Children.create();

    for (int i = 0; i < 32; i++) {
      builder.child(
          SingleComponentSection.create(c)
              .key(String.valueOf(i))
              .component(ListItem.create(c).build()));
    }
    return builder.build();
  }
}

解釋:
SingleComponentSection 是 Litho Section API 提供中的一個(gè)核心 Section,定義在 com.facebook.litho.sections.widget 這個(gè)包中搂鲫,只不過這個(gè) Section 負(fù)責(zé)渲染一個(gè)單一的 Component 傍药。ListSectionSpec 描述了一個(gè)包含有 32 個(gè)子 Section 的 Section ,這 32 個(gè)子 Section 中默穴,每個(gè) Section 負(fù)責(zé)渲染一個(gè) ListItem 組件怔檩。
這里定義的是 Section ,并沒有定義 Component蓄诽,那么如何把 Section 顯示在屏幕上薛训?
把 Activity 中組件的定義改成下面的代碼:

final Component component =
    RecyclerCollectionComponent.create(context)
        .disablePTR(true)
        .section(ListSection.create(new SectionContext(context)).build())
        .build();

注意:這里使用的是 ListSection ,而不是 ListSectionSpec 仑氛。

解釋:

這里我們用 RecyclerCollectionComponent 這個(gè)組件乙埃,把剛剛定義的Section 顯示在屏幕上。 RecyclerCollectionComponent 接收一個(gè) Section 作為屬性锯岖,會(huì)渲染一個(gè) RecyclerView 顯示 Section中的內(nèi)容介袜。它來管理數(shù)據(jù)刷新的操作,這里不使用下拉刷新功能出吹,所以 通過設(shè)置 .disablePTR(true) 把這個(gè)功能關(guān)掉遇伞。

運(yùn)行代碼,效果如下:

列表實(shí)現(xiàn)1

定義組件的屬性

上面的列表中捶牢,我們所有的列表項(xiàng)都顯示重復(fù)的內(nèi)容鸠珠,現(xiàn)在我們想要列表中的內(nèi)容是變化的巍耗。
這里引入 Litho 中屬性的概念,也就是 Prop 渐排。Component 的屬性就是 Component Spec 類(這個(gè)類是我們編寫用于生成對(duì)應(yīng)的 Component 類的)中方法的參數(shù)炬太,這些參數(shù)上帶有 @Prop 注解。

把 ListItemSpec 進(jìn)行如下修改:

@OnCreateLayout
static Component onCreateLayout(
    ComponentContext c,
    @Prop int color,
    @Prop String title,
    @Prop String subtitle) {

  return Column.create(c)
        .paddingDip(ALL, 16)
        .backgroundColor(color)
        .child(
            Text.create(c)
                .text(title)
                .textSizeSp(40))
        .child(
            Text.create(c)
                .text(subtitle)
                .textSizeSp(20))
        .build();
}

解釋:
這里我們添加了三個(gè)屬性驯耻,color亲族,title,subtitle 可缚。這里的 backgroundColor 以及 Text 組件的 文本內(nèi)容不再是硬編碼的形式霎迫,而是根據(jù) onCreateLayout 方法中的參數(shù)給出。

Litho 的注解處理器會(huì)根據(jù) @Prop 注解城看,為注解的參數(shù)生成相應(yīng)的構(gòu)造器方法女气,例如這里參數(shù)名稱是 color,就會(huì)為 ListItem 生成 color(int) 方法测柠,相應(yīng)地炼鞠,這里還會(huì)生成另外兩個(gè)構(gòu)造器方法,title(String) ,subtitle(String) 轰胁。在創(chuàng)建 ListItem 組件的時(shí)候谒主,就需要在構(gòu)造器方法中,對(duì)屬性進(jìn)行賦值赃阀。

修改 ListSection 中的方法:

@OnCreateChildren
static Children onCreateChildren(final SectionContext c) {
  Children.Builder builder = Children.create();

  for (int i = 0; i < 32; i++) {
    builder.child(
        SingleComponentSection.create(c)
            .key(String.valueOf(i))
            .component(ListItem.create(c)
               .color(i % 2 == 0 ? Color.WHITE : Color.LTGRAY)
               .title(i + ". Hello, world!")
               .subtitle("Litho tutorial")
               .build()));
  }
  return builder.build();
}

另外霎肯,屬性上還可以有其他選項(xiàng),例如:
@Prop(optional = true, resType = ResType.DIMEN_OFFSET) int shadowRadius,

注解處理器還會(huì)生成一些對(duì)應(yīng)的方法 :shadowRadiusPx, shadowRadiusDip, shadowRadiusSp 以及 shadowRadiusRes榛斯。

注意:

  1. Prop 可以被 Spec 中不同的生命周期方法訪問观游,只需要在相應(yīng)的方法參數(shù)上添加這個(gè) Prop ,Litho 保證每個(gè)方法訪問到的屬性值是一致的驮俗,但是要保證同一個(gè)Prop 在不同方法中的聲明完全一致懂缕,比如 方法1 中 使用 @Prop(optional = true) String prop1,那么 方法2 中也要采用 @Prop(optional = true) String prop1, 否則注解處理器會(huì)報(bào)錯(cuò)。
  2. 另外對(duì)于 optional = true 的屬性王凑,在組件創(chuàng)建時(shí)可不傳入該屬性的值搪柑,如果未添加此項(xiàng)設(shè)置,則會(huì)在運(yùn)行時(shí)報(bào)如下錯(cuò)誤:下面是我把上面代碼中的 subtitle一樣注釋掉報(bào)的錯(cuò):
    java.lang.IllegalStateException: The following props are not marked as optional and were not supplied: [subtitle]
    有關(guān)屬性的問題索烹,請(qǐng)參考 Props

運(yùn)行APP工碾,會(huì)看到如下效果:


列表實(shí)現(xiàn)-帶屬性
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市百姓,隨后出現(xiàn)的幾起案子渊额,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件端圈,死亡現(xiàn)場(chǎng)離奇詭異焦读,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)舱权,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仑嗅,“玉大人宴倍,你說我怎么就攤上這事〔旨迹” “怎么了鸵贬?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)脖捻。 經(jīng)常有香客問我阔逼,道長(zhǎng),這世上最難降的妖魔是什么地沮? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任嗜浮,我火速辦了婚禮,結(jié)果婚禮上摩疑,老公的妹妹穿的比我還像新娘危融。我一直安慰自己,他們只是感情好雷袋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布吉殃。 她就那樣靜靜地躺著,像睡著了一般楷怒。 火紅的嫁衣襯著肌膚如雪蛋勺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天鸠删,我揣著相機(jī)與錄音抱完,去河邊找鬼。 笑死冶共,一個(gè)胖子當(dāng)著我的面吹牛乾蛤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捅僵,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼家卖,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了庙楚?” 一聲冷哼從身側(cè)響起上荡,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后酪捡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叁征,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年逛薇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了捺疼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡永罚,死狀恐怖啤呼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情呢袱,我是刑警寧澤官扣,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站羞福,受9級(jí)特大地震影響惕蹄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜治专,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一卖陵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧看靠,春花似錦赶促、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至谤祖,卻和暖如春婿滓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背粥喜。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工凸主, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人额湘。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓卿吐,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親锋华。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嗡官,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)毯焕,斷路器衍腥,智...
    卡卡羅2017閱讀 134,654評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,810評(píng)論 6 342
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong閱讀 22,396評(píng)論 1 92
  • 凌寒夜冷風(fēng), 蹣跚雨中行婆咸, 繁逝悲由空寂寥竹捉。 唯犬吠知更獨(dú)行! 徒步到?jīng)龀浚?荒雞難鳴尚骄。 應(yīng)化流風(fēng)水?dāng)啾?世道怎...
    夏墨凌語(yǔ)閱讀 169評(píng)論 0 5
  • 1块差、15年底以前,我抵抗低落情緒的時(shí)候使用最多的方法之一就是跑步乖仇。 2憾儒、不幸的是,左膝關(guān)節(jié)外側(cè)長(zhǎng)年積累發(fā)生疼痛乃沙,5...
    五彩冰峰閱讀 192評(píng)論 0 0