1. 程式人生 > >RecyclerView讓列表巢狀如此簡單

RecyclerView讓列表巢狀如此簡單

平常開發時,相信像這樣的頁面,大家一定是遇到過的。這裡比較坑爹的地方在於呢:列表巢狀。訂單列表中的每一項,都包含一個商品列表。像這種需求,大家會如何實現呢?

這裡呢,說一下我自己的思路,我沒有使用列表巢狀,而是,將原有的Order拆分成了三個佈局型別:Head、Body、Foot,一個Body就是一個商品,有多個商品就有多個Body。

然後,使用我自己封裝的一套Adapter,讓多佈局更加簡單易用。關於我的這個Adapter庫,詳見:Adapter的封裝之路

不過,這裡稍稍麻煩的一點就是,得到網路資料之後,我們需要對原始的List<Order>進行加工,轉換成我們需要的List<LayoutWrapper>,具體轉換的方法,類似於我這裡的mockData裡面的方法。

每一個LayoutWrapper都會持有:佈局id、實體類、實體的展示類

其實,這裡的實體展示類,如果是公用的,最好不要做成內部類,做成外部類

複製程式碼

/**
 * 今日訂單數
 * <p>
 * 作者:余天然 on 2017/3/6 下午12:01
 */
@Route(path = "/home/order")
public class TodayOrderActivity extends BaseActivity {

    @BindView(R.id.rv_content)
    RecyclerView rvContent;

    int[] layoutIds = {
            R.layout.item_home_order_head,
            R.layout.item_home_order_body,
            R.layout.item_home_order_foot,
            R.layout.item_divider10_gray,
            R.layout.item_divider10_white,
    };

    SuperAdapter adapter;

    @Override
    protected int createLayoutId() {
        return R.layout.activity_today_order;
    }

    @Override
    public void initWidget() {
        setTitleText("今日訂單");

        rvContent.setLayoutManager(new LinearLayoutManager(this));
        adapter = new SuperAdapter(this, layoutIds);
        rvContent.setAdapter(adapter);
        DividerFactory.setDivider(rvContent, DividerType.FOOT, R.color.gray_divider, R.dimen.divider_1, LinearLayoutManager.VERTICAL);

        adapter.setData(mockData());
    }

    private List<LayoutWrapper> mockData() {
        List<LayoutWrapper> wrappers = new ArrayList<>();
        wrappers.add(new LayoutWrapper(R.layout.item_divider10_gray, "", null));
        wrappers.add(new LayoutWrapper(R.layout.item_home_order_head, "廣州尚都布業", headDisplayer));
        wrappers.add(new LayoutWrapper(R.layout.item_home_order_body, "一鍵開單", bodyDisplayer));
        wrappers.add(new LayoutWrapper(R.layout.item_home_order_foot, new FootItem(1, "90.00"), footDisplayer));

        wrappers.add(new LayoutWrapper(R.layout.item_divider10_gray, "", null));
        wrappers.add(new LayoutWrapper(R.layout.item_home_order_head, "王鵬", headDisplayer));
        wrappers.add(new LayoutWrapper(R.layout.item_home_order_body, "全棉色織格子布", bodyDisplayer));
        wrappers.add(new LayoutWrapper(R.layout.item_divider10_white, "", null));
        wrappers.add(new LayoutWrapper(R.layout.item_home_order_body, "尼龍", bodyDisplayer));
        wrappers.add(new LayoutWrapper(R.layout.item_home_order_foot, new FootItem(2, "170.00"), footDisplayer));

        return wrappers;
    }

    DataDisplayer<String> headDisplayer = new DataDisplayer<String>() {
        @Override
        public void bindData(BaseViewHolder holder, String item, int position) {
            holder.setText(R.id.tv_name, item);
        }
    };

    DataDisplayer<String> bodyDisplayer = new DataDisplayer<String>() {
        @Override
        public void bindData(BaseViewHolder holder, String item, int position) {
            holder.setText(R.id.tv_goods, item);
        }
    };


    DataDisplayer<FootItem> footDisplayer = new DataDisplayer<FootItem>() {
        @Override
        public void bindData(BaseViewHolder holder, FootItem item, int position) {
            String price = String.format("合計  ¥%s", item.price);
            String number = String.format("(共%s件商品 優惠¥12 運費到付)", item.number);
            holder.setText(R.id.tv_total_price, price);
            holder.setText(R.id.tv_total_number, number);
        }
    };

    class FootItem {
        Integer number;
        String price;

        public FootItem(Integer number, String price) {
            this.number = number;
            this.price = price;
        }
    }
}

複製程式碼