我正在用Java创建一个Android应用,正在使用Room数据库。 我有三张桌子:
Users table( user_id and user_name)
Products table( product_id and product_name)
Orders table ( order_id , user_id and product_id )
我正在使用ViewModel查询信息并将其填充到UI。
我有一个从Orders表user_id
和product_id
获取的查询。
我有这种情况:
user_id 1号已订购3个产品。
private void setUpViewModel() {
viewModel.getUserProduct(1).observe(this,new Observer<List<OrdersTable>>() {
@Override
public void onChanged(@Nullable List<OrdersTable> order) {
mAdapter.setUserList((ArrayList<OrdersTable>) order);
}
}
);
}
此查询将为用户1获得产品1,2和3
我想在recylcerView
中显示用户名和产品名,但是我不知道如何在recylcerView
中显示两种不同类型的表(用户表和产品表)。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_userName_xml"
android:text="user name"
android:layout_margin="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_prodcutName_xml"
android:layout_marginLeft="40dp"
android:text="product"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private Context mContext;
ArrayList<OrderTable> order_list;
ArrayList<UserTable> user_list;
ArrayList<ProductTable> product_list;
public MyAdapter(Context context) {
this.mContext = context;
}
@NonNull
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_ts, parent, false);
MyAdapter.MyViewHolder viewHolder = new MyAdapter.MyViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull MyAdapter.MyViewHolder holder, int position) {
OrderTable orders = order_list.get(position);
UserTable user = user_list.get(position);
ProductTable productTable = product_list.get(position);
holder.tv_userName.setText(user.getUserName());
holder.tv_productName.setText(productTable.getProductName());
}
@Override
public int getItemCount() {
if (order_list == null) {
return 0;
}
return order_list.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView tv_userName, tv_productName;
public MyViewHolder(View itemView) {
super(itemView);
tv_userName= itemView.findViewById(R.id.tv_userName_xml);
tv_productName= itemView.findViewById(R.id.tv_prodcutName_xml);
}
}
public void setTs_list(ArrayList<OrderTable> ts) {
this.order_list = ts;
notifyDataSetChanged();
}
}
答案 0 :(得分:1)
您可以联接这些表中的数据,并将其绑定到名为ResultModel
的自定义模型类中。您可以从该user_name
中获得product_name
和ResultModel
用户表
产品表
t_order 表
加入查询:
从用户u,产品p,t_order o中选择u.user_name,p.product_name 其中o.user_id = u.user_id和o.product_id = p.product_id
结果
创建一个模型类ResultModel
public class ResultModel {
public String getUser_name() {
return user_name;
}
public String getProduct_name() {
return product_name;
}
private String user_name;
private String product_name;
}
更新的观察者
注意:在您的OrdersTable
中,也需要用ResultModel
替换Adapter
viewModel.getUserProduct(1).observe(this,new Observer<List<ResultModel>>() {
@Override
public void onChanged(@Nullable List<ResultModel> order) {
mAdapter.setUserList((ArrayList<ResultModel>) order);
}
}
);
}
答案 1 :(得分:0)
您可以像这样在onBindViewHolder中创建多个回收视图
@Override
public void onBindViewHolder(ItemRowHolder itemRowHolder, int i) {
final String sectionName = dataList.get(i).getHeaderTitle();
ArrayList singleSectionItems = dataList.get(i).getAllItemsInSection();
itemRowHolder.itemTitle.setText(sectionName);
SectionListDataAdapter itemListDataAdapter = new SectionListDataAdapter(mContext, singleSectionItems);
itemRowHolder.recycler_view_list.setHasFixedSize(true);
itemRowHolder.recycler_view_list.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false));
itemRowHolder.recycler_view_list.setAdapter(itemListDataAdapter);
}
public class ItemRowHolder extends RecyclerView.ViewHolder {
protected TextView itemTitle;
protected RecyclerView recycler_view_list;
public ItemRowHolder(View view) {
super(view);
this.itemTitle = (TextView) view.findViewById(R.id.itemTitle);
this.recycler_view_list = (RecyclerView) view.findViewById(R.id.recycler_view_list);
}
}
答案 2 :(得分:-1)
我的建议是使用不同的视图类型。 Here is an article about it
首先,您必须为适配器提供数据源的抽象。通常,我们有一个简单的数组或一个列表作为数据源,但是在您的情况下,您只有三种类型。因此,您可以创建一个接口或使用一个集合将所有数据存储在适配器中,具体取决于您如何制作。 之后,您必须为每种类型的模型创建不同的常量。在您的示例中,您具有三个模型:用户,产品和订单。因此,我建议为每种类型创建三个常量。这些常量应作为静态字段放置在适配器类中。
private static final int USER_VIEW_TYPE = 1;
private static final int PRODUCT_VIEW_TYPE = 2;
private static final int ORDER_VIEW_TYPE = 3;
然后,您必须在适配器中覆盖方法getItemViewType(int position)
。在这里,您必须告诉适配器特定项目的类型。例如,您已决定将所有数据存储为List<Object>
(但不要在生产代码中这样做,例如,我在这里使用Object
类型。)。因此,在这种情况下,您的方法将如下所示:
@Override public int getItemViewType(int position) {
if (data[position] instanceof User) {
return USER_VIEW_TYPE;
} else if (data[position] instanceof PRODUCT_VIEW_TYPE) {
return PRODUCT_VIEW_TYPE;
} else return ORDER_VIEW_TYPE;
}
此后,您需要为您的类型创建不同的ViewHolders,因此您将拥有一个UserViewHolder
,一个ProductViewHolder
和一个OrderViewHolder
。
并且,为了最终区分它们,您应该在viewType
方法中使用onCreateViewHolder
参数。逻辑很简单:您必须检查此参数的值,并根据结果对不同的布局进行充气。例如:
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
if (viewType == USER_VIEW_TYPE) {
return new UserViewHolder(layoutInflater.inflate(R.layout.item_user_type, parent));
} else if (viewType == PRODUCT_VIEW_TYPE) {
return new ProductViewHolder(layoutInflater.inflate(R.layout.item_product_type, parent));
} else return new OrderViewHolder(layoutInflater.inflate(R.layout.item_order_type, parent));
}