如何使用两个数据模型在 RecyclerView 中创建多个视图类型? [英] How to make multiple view type in RecyclerView using two data models?

查看:59
本文介绍了如何使用两个数据模型在 RecyclerView 中创建多个视图类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有使用 Retrofit 库从 API 获取的数据.API 完美运行.问题是如何将数据放入列表并使用 RecyclerView 适配器显示它.我尝试使用 HashMap 但它会使应用程序崩溃.有人可以帮我展示这个问题的正确结构和解决方案吗?

I have the data that I get from API using the Retrofit library. The API working perfectly. The problem is how do I put the data into the list and display it using RecyclerView adapter. I tried using HashMap but it will crash the application. Can someone help me to show the right structure and solution of this issue?

API 数据

报表模型

在报表列表中记录模型

我已经从 API 获得的数据

The data I already got from the API

我想显示的界面

推荐答案

我建议你扁平化模型.与其让父母带着孩子,不如只有一个级别.此外,为您的 UI 和 Retrofit 使用不同的数据模型.需要时,在模型之间进行转换.这样,事情就不是紧密耦合的,你可以在覆盖时做其他事情,例如如果需要,格式化字符串.

I suggest you flatten the model. Instead of having a parent with a child, have only one level. Also, use different data models for your UI and for Retrofit. When needed, convert between the models. This way, things are not tightly coupled and you can do other things when coverting, e.g. format strings if needed.

// This is what the data model will extend
interface UiBaseModel { }

// monthly detail report
class UiMonthlyDetailReport implements UiBaseModel {

    private String month;
    private String total;

    UiMonthlyDetailReport(String month, String total) {
        this.month = month;
        this.total = total;
    }

    public String getMonth() {
        return month;
    }

    public String getTotal() {
        return total;
    }
}

// monthly detail record
class UiMonthlyDetailsRecord implements UiBaseModel {

    private String month;
    private String expenseName;
    private String expenseIcon;
    private String expenseTotal;

    UiMonthlyDetailsRecord(String month, String expenseName, String expenseIcon, String expenseTotal) {
        this.month = month;
        this.expenseName = expenseName;
        this.expenseIcon = expenseIcon;
        this.expenseTotal = expenseTotal;
    }

    public String getMonth() {
        return month;
    }

    public String getExpenseName() {
        return expenseName;
    }

    public String getExpenseIcon() {
        return expenseIcon;
    }

    public String getExpenseTotal() {
        return expenseTotal;
    }
}



// In your activity / fragment / viewmodel / presenter:

    List<ReportMonthlyDetailsReport> reports = ... // get your data from retrofit
    List<UiBaseModel> uiModels = ArrayList<UiBaseModel>();
    for (ReportMonthlyDetailsReport report : reports) {
        // First records, then report
        List<ReportMonthlyDetailsRecord> records = report.getRecords();
        for (ReportMonthlyDetailsRecord record : records) {
            // Create UI model and add to list
            UiMonthlyDetailsRecord uiRecord = UiMonthlyDetailsRecord(record.getMonth_label(), record.getExpense_type_name(), record.getExpense_type_icon(), record.getExpense_type_total());
            uiModels.add(uiRecord);
        }
        // Lastly, add the report
        UiMonthlyDetailsReport uiReport = UiMonthlyDetailsReport(report.getMonth_label(), report.getMonthly_total());
        uiModels.add(uiReport);
    }

    // Use the ui models (for the recycler adapter)
    MonthlyDetailsAdapter adapter = MonthlyDetailsAdapter(uiModels);
    recyclerView.adapter = adapter;

剩下要做的就是适配器.有很多关于如何支持多种视图类型的示例,简单的未完成示例:

All that's left to do is the adapter. There are plenty examples on how to support multiple view types, simple unfinished example:

public class MonthlyDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private final static int VIEW_TYPE_RECORD = 0;
    private final static int VIEW_TYPE_REPORT = 1;

    private List<UiBaseModel> data;

    MonthlyDetailsAdapter(List<UiBaseModel> data) {
        this.data = data;
    }

    class RecordViewHolder extends RecyclerView.ViewHolder {
        public RecordViewHolder(@NonNull View itemView) {
            // code
            super(itemView);
        }
    }

    class ReportViewHolder extends RecyclerView.ViewHolder {
        public ReportViewHolder(@NonNull View itemView) {
            // code
            super(itemView);
        }
    }

    @Override
    public int getItemViewType(int position) {
        UiBaseModel item = data.get(position);
        if (item instanceof UiMonthlyDetailsRecord) {
            return VIEW_TYPE_RECORD;
        } else {
            return VIEW_TYPE_REPORT;
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof RecordViewHolder) {
            UiMonthlyDetailsRecord record = (UiMonthlyDetailsRecord) data.get(position);
            // bind record
        } else if (holder instanceof ReportViewHolder) {
            UiMonthlyDetailsReport report = (UiMonthlyDetailsReport) data.get(position);
            // bind report
        }
    }
}

这篇关于如何使用两个数据模型在 RecyclerView 中创建多个视图类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆