我是Android的新手,我不确定自己缺少什么。
我正在制作一个跟踪您的日常开支的应用程序。因此,我在房间db中有4个表:expenses,tags,expenses_tags_join和pics。费用可以有多个标签和多个图片。
我的问题是显示在一个recyclerview项目上带有三个标签的一笔费用。我使用私有List<String> tag_name
属性制作了模型“ DailyExpenseModel”,但出现错误:
“无法弄清楚如何从cursor.private读取此字段。 列出tag_name;“
如果我改用private String ttag_name
,那么当我遍历标签时,recyclerview适配器将产生重复的费用。
我知道我无法在onBindViewHolder内进行数据库查询(起初这似乎是最简单的解决方案),而且我还在考虑实现多种视图类型,但是我不确定在我的情况下是否需要这样做。基本上,我不知道如何将我的标签(和图片)列表从db传输到我的视图持有者。
适配器:
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;
}
}
ViewModel:
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);
}
答案 0 :(得分:0)
我的解决方案非常简单。全部与@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);
}