Litho

Litho学习--列表的实现-2

2018-05-21  本文已影响67人  言者无知_n4c

接着上篇 简单的列表-1,这一篇主要讲解如何在列表的顶部添加一个水平滚动的列表,充分利用 Litho 和 Section API 的可组合性。

简单的列表-1 中 ListSectionSpec 描述了一个包含有 32 个子 SingleComponentSection 的 GroupSection ,每个 SingleComponentSection 负责渲染一个 ListItem Component,每个 Component 的内容只有显示的数字发生了变化。

这篇中将利用 Litho 中的另外一个核心 Section :DataDiffSection 来渲染列表, 我们把 ListSectionSpec 中的 SingleComponentSection 替换成 DataDiffSection 。

本篇中的例子把上篇例子中的 ListItemSpec 变成了 ListItem2Spec , ListSectionSpec 变成了 ListSection2Spec, ListSectionSpec 与 ListItemSpec 对应,ListSection2Spec 与 ListItem2Spec 对应。

1. 重构列表

首先,把 ListItemSpec 中的三个属性抽取为一个数据模型:

public class DataModel {
    public String title;
    public String subtitle;
    public int color;
}

把 ListItemSpec 按照如下修改:

@LayoutSpec
public class ListItem2Spec {

    @OnCreateLayout
    static Component onCreateLayout(
            ComponentContext c,
            @Prop DataModel dataModel) {

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

在 ListSection2Spec 中添加生成列表的方法,这里使用静态方法模拟,实际场景应该是拉取数据:

 private static List<DataModel> generateData(int count) {
        final List<DataModel> data = new ArrayList<>(count);
        for (int i = 0; i < count; i++) {
            DataModel model = new DataModel();
            model.color = (i % 2 == 0 ? Color.WHITE : Color.LTGRAY);
            model.title = i + ". Hello, world!";
            model.subtitle = "Litho tutorial";
            data.add(model);
         }
        return data;
    }

再写一个方法,接收 DataModel 参数,创建一个 ListItem2 。

@OnEvent(RenderEvent.class)
    static RenderInfo onRender(final SectionContext c, @FromEvent DataModel model,@FromEvent int index) {
        return ComponentRenderInfo.create()
                .component(
                        ListItem2.create(c)
                                .dataModel(model)
                                .build())
                .build();
    }

接下来把两个方法结合在一起,修改 onCreateChildren 方法:

@OnCreateChildren
    static Children onCreateChildren(final SectionContext c) {
        return Children.create()
                .child(
                        DataDiffSection.<DataModel>create(c)
                                .data(generateData(32))
                                .renderEventHandler(ListSection2.onRender(c)))
                .build();
    }

那么 @OnEvent 是什么东西?ListSection2.onRender(c) 又是怎么来的?
下面简单解释一下:

运行APP,效果如下:


简单列表实现-2

2. 添加水平滚动列表

还记得我们是如何用RecyclerCollectionComponent来创建列表的么?应为RecyclerCollectionComponent自身也是一个Component,所以我们可以在Section里再创建一个列表,轻松实现嵌套列表。在一个垂直的列表中再嵌套一个垂直的列表是没有意义的,比较常见的是在垂直列表中嵌入一个水平列表。接下来我们就要这么做。

更新 onCreateChildren()中的代码,在DataDiffSection前面加一个SingleComponentSection:

    @OnCreateChildren
    static Children onCreateChildren(final SectionContext c) {
        return Children.create()
            .child(
                SingleComponentSection.create(c)
                .component(
                    RecyclerCollectionComponent.create(c)
                        .disablePTR(true)
                        .recyclerConfiguration(new ListRecyclerConfiguration(LinearLayoutManager.HORIZONTAL, /*reverse layout*/ false, SNAP_TO_CENTER))
                        .section(
                            DataDiffSection.<DataModel>create(c)
                                .data(generateData(32))
                                .renderEventHandler(ListSection2.onRender(c))
                        )
                        .canMeasureRecycler(true)
                )
                .build()
            )
            .child(
                DataDiffSection.<DataModel>create(c)
                    .data(generateData(32))
                    .renderEventHandler(ListSection2.onRender(c))
            )
            .build();
    }

这里我们看到 RecyclerCollectionComponent 的几个新 props:

运行APP,应该会看到如下画面:

简单列表-2-带水平列表
上一篇下一篇

猜你喜欢

热点阅读