【问题标题】:Showing data in RecyclerView from multiple Room database tables在 RecyclerView 中显示来自多个 Room 数据库表的数据
【发布时间】:2020-04-25 16:45:49
【问题描述】:

我是 Android 新手,我不确定我错过了什么。

我正在制作一个应用程序来跟踪您的日常开支。所以,我在房间 db 中有 4 个表:费用、标签、费用标签连接和图片。费用可以有多个标签和多张图片。

我的问题是显示例如一项费用,在一项 recyclerview 项目上带有三个标签。我使用私有List<String> tag_name 属性创建了模型“DailyExpenseModel”,但出现错误:

"无法弄清楚如何从 cursor.private 中读取此字段 列出标签名称;"

如果我改为使用 private String ttag_name,那么当我遍历标签时,recyclerview 适配器会重复费用。

我知道我无法在 onBindViewHolder 中进行数据库查询(起初这似乎是最简单的解决方案),而且我也在考虑实现多种视图类型,但我不确定在我的情况下是否需要这样做。基本上,我不知道如何将我的标签(和图片)列表从数据库传输到我的视图。

适配器:

public class DailyCostAdapter extends RecyclerView.Adapter<DailyCostAdapter.DailyCostViewHolder> {

    // Member variable to handle item clicks
    final private DailyItemClickListener mDailyItemClickListener;

    // Class variables for the List that holds cost data and the Context
    private List<DailyExpenseModel> mDailyExpenseModelEntries;

    //  private List<TagEntry> mTagEntries;
    private Context mContext;
    private CostDatabase mDb;

    //private ImageView imgv_category;

    public DailyCostAdapter(DailyItemClickListener listener, Context context) {
        mDailyItemClickListener = listener;
        mContext = context;
    }

    /**
     * Called when ViewHolders are created to fill a RecyclerView.
     *
     * @return A new DailyCostViewHolder that holds the view for daily costs
     */
    @NonNull
    @Override
    public DailyCostViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //Inflate the layout to the view
        View view = LayoutInflater.from(mContext)
                .inflate(R.layout.one_cost_item_view, parent, false);

        return new DailyCostViewHolder(view);
    }

    /**
     * Called by the RecyclerView to display data at a specified position in the Cursor.
     *
     * @param holder   The ViewHolder to bind Cursor data to
     * @param position The position of the data in the Cursor
     */
    @Override
    public void onBindViewHolder(@NonNull final DailyCostViewHolder holder, int position) {
        // Determine the values of the wanted data
        DailyExpenseModel dailyExpenseModelEntry = mDailyExpenseModelEntries.get(position);

        //individual cost on particular day
        String oneCostCategory = dailyExpenseModelEntry.getEcategory();
        String oneCostName = dailyExpenseModelEntry.getEname();
        int oneCostValue = dailyExpenseModelEntry.getEcost();
        String oneCostValueString = Helper.fromIntToDecimalString(oneCostValue);
        final int CostId = dailyExpenseModelEntry.getEid();

        List<String> oneCostTags = new ArrayList<>();
        oneCostTags.addAll(dailyExpenseModelEntry.getTtag_name());
//        oneCostTags.add(tag);

        //Set other values
        holder.tv_costDescription.setText(oneCostName);
        holder.tv_costValue.setText(currency1 + oneCostValueString + currency2);

        holder.cg_tagsDailyCost.removeAllViews();
        for (String s : oneCostTags) {
            Chip chip = new Chip(mContext);
            chip.setText(s);
            holder.cg_tagsDailyCost.addView(chip);
        }

DailyExpenseModel(绑定所有实体的数据):

public class DailyExpenseModel  {
    public int eid;
    public String ecategory;
    public String ename;
    public int ecost;
    public String edate;
    private List<String> ttag_name;
    private List<String> ppic_uri;
    private List<String> ppic_name;

    public DailyExpenseModel(int eid, String ecategory, String ename, int ecost, String edate,
                             List<String> ttag_name, List<String> ppic_uri, List<String> ppic_name) {
        this.eid = eid;
        this.ecategory = ecategory;
        this.ename = ename;
        this.ecost = ecost;
        this.edate = edate;
        this.ttag_name = ttag_name;
        this.ppic_uri = ppic_uri;
        this.ppic_name = ppic_name;
    }

    public int getEid() {
        return eid;
    }

    public String getEcategory() {
        return ecategory;
    }

    public String getEname() {
        return ename;
    }

    public int getEcost() {
        return ecost;
    }

    public String getEdate() {
        return edate;
    }

    public List<String> getTtag_name() {
        return ttag_name;
    }

    public List<String> getPpic_uri() {
        return ppic_uri;
    }

    public List<String> getPpic_name() {
        return ppic_name;
    }
}

视图模型:

public class DailyExpensesViewModel extends ViewModel {

    private LiveData<List<DailyExpenseModel>> costs;

    public DailyExpensesViewModel(CostDatabase database, String date) {
        costs = database.dailyExpensesDao().loadEverythingForDate(date);
    }

    public LiveData<List<DailyExpenseModel>> getCosts() {
        return costs;
    }

}

Dao(为简单起见,不包括 PicsEntry 数据):

@Dao
public interface DailyExpensesDao {

    @Query("SELECT e.id AS eid, e.category AS ecategory, e.name AS ename, e.cost AS ecost, e.date AS edate," +
            " t.tag_name AS ttag_name FROM expenses e " +
            "LEFT JOIN expenses_tags_join et ON e.id = et.expense_id " +
            "LEFT JOIN tags t ON et.tag_id = t.tag_id WHERE edate = :date")
    LiveData<List<DailyExpenseModel>> loadEverythingForDate(String date);

}

【问题讨论】:

    标签: java android android-recyclerview android-room


    【解决方案1】:

    我的解决方案非常简单。这都是关于 @Relation 注释的:here

    DailyExpenseModel(我将其重命名为 DailyExpenseTagsWithPicsPojo):

    public class DailyExpenseTagsWithPicsPojo {
    
        public DailyExpenseTagsWithPicsPojo() {
        }
    
        @Embedded
        public CostEntry costEntry;
    
        @Relation(parentColumn = "id",
                entityColumn = "tag_id",
                entity = TagEntry.class,
                projection = {"tag_name"},
                associateBy = @Junction(value = Expenses_tags_join.class,
                parentColumn = "expense_id",
                entityColumn = "tag_id"))
        private List<String> tagNames;
    
        @Relation(parentColumn = "id",
                entityColumn = "expense_id",
                entity = PicsEntry.class)
        private List<PicsEntry> picsEntries;
    
    
        public CostEntry getCostEntry() {
            return costEntry;
        }
    
        public void setCostEntry(CostEntry costEntry) {
            this.costEntry = costEntry;
        }
    
        public List<String> getTagNames() {
            return tagNames;
        }
    
        public void setTagNames(List<String> tagNames) {
            this.tagNames = tagNames;
        }
    
        public List<PicsEntry> getPicsEntries() {
            return picsEntries;
        }
    
        public void setPicsEntries(List<PicsEntry> picsEntries) {
            this.picsEntries = picsEntries;
        }
    
    }
    

    适配器:

     @Override
        public void onBindViewHolder(@NonNull final DailyCostViewHolder holder, int position) {
            // Determine the values of the wanted data
            DailyExpenseTagsWithPicsPojo dailyExpenseTagsWithPicsPojo = mdailyExpenseTagsWithPicsPojos.get(position);
    
            //individual cost on particular day
            String oneCostCategory = dailyExpenseTagsWithPicsPojo.getCostEntry().getCategory();
            String oneCostName = dailyExpenseTagsWithPicsPojo.getCostEntry().getName();
            int oneCostValue = dailyExpenseTagsWithPicsPojo.getCostEntry().getCost();
            String oneCostValueString = Helper.fromIntToDecimalString(oneCostValue);
            List<String> oneCostTags = dailyExpenseTagsWithPicsPojo.getTagNames();
            List<PicsEntry> picsEntries = dailyExpenseTagsWithPicsPojo.getPicsEntries();
    
            for (PicsEntry picsEntry : picsEntries) {
                String uri = picsEntry.getPic_uri();
            }
    
              //Set other values
            holder.tv_costDescription.setText(oneCostName);
            holder.tv_costValue.setText(currency1 + oneCostValueString + currency2);
    
            if (oneCostTags != null) {
                for (String s : oneCostTags) {
                    Chip chip = new Chip(mContext);
                    chip.setText(s);
                    holder.cg_tags.addView(chip);
                }
            }
            //set holder for pics uri...
    

    @Dao:

    @Dao
    public interface DailyExpensesDao {
    
        @Transaction
        @Query("SELECT * FROM expenses WHERE date =:date")
        LiveData<List<DailyExpenseTagsWithPicsPojo>> loadCostsWithTagsAndPics(String date);
    }
    

    【讨论】:

      猜你喜欢
      • 2021-08-28
      • 2020-02-01
      • 1970-01-01
      • 2021-11-09
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多