我正在使用房间数据库创建Android应用。 我有两个表DogsTable:
@PrimaryKey(autoGenerate = true)
int dog_id;
String dogName;
和CatsTable(两个表都有构造函数和getter方法):
@PrimaryKey(autoGenerate = true)
int cat_id;
String catName;
1-如何在一个RecyclerView中显示两种不同的对象类型
ArrayList<DogsTable> dog_list;
ArrayList<CatsTable> cat_list;
我正在从ViewModel查询中获取dog_list和cat_list的值,如MainActivity.class中所示。
2-如何解决getItemCount()
方法?我不知道如何返回两个不同的对象cat_list.size();
和dog_list.size();
3-还是在onBindViewHolder()
方法中,我不知道如何获取cat_list值以在UI中显示它们?
4-另一个问题是swapToDelete()
的{{1}}方法中,我可以获取删除它的狗id,但是我无法获取删除它的cat id,我该如何获取猫ID ?
5-如何显示(dog1,dog2,dog3)为第一张图片所示? (我将值手动插入到第一张图像中只是为了显示我要如何显示它们)
MainActivity.class
我的代码
MainActivity.java
Existing Output as below:
activity_main.xml
public class MainActivity extends AppCompatActivity implements MainActivityAdapter.ItemClickListener {
MyViewModel viewModel;
MainActivityAdapter adapter;
RecyclerView recyclerView;
LinearLayoutManager layoutManager;
Button btn_addDog, btn_addCat;
EditText et_addDogName, et_addCatName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
viewModel = ViewModelProviders.of(this).get(MyViewModel.class);
actionButton();
buildRecyclerView();
setUpViewModel_dogs();
swapToDelete_dog();
}
private void initViews() {
et_addDogName = findViewById(R.id.addDogNameET_xml);
et_addCatName = findViewById(R.id.addCatNameET_xml);
}
public void actionButton() {
btn_addDog = findViewById(R.id.AddDog_btn_xml);
btn_addCat = findViewById(R.id.AddCat_btn_xml);
btn_addDog.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
insertDog();
}
});
btn_addCat.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
insertCat();
}
});
}
private void buildRecyclerView() {
recyclerView = findViewById(R.id.recyclerView_id);
adapter = new MainActivityAdapter(this, this);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
// Query
public void setUpViewModel_dogs() {
viewModel = ViewModelProviders.of(this).get(MyViewModel.class);
viewModel.getAllDogs().observe(this, new Observer<List<DogsTable>>() {
@Override
public void onChanged(@Nullable List<DogsTable> dogsTables) {
adapter.setDog_list((ArrayList<DogsTable>) dogsTables);
}
});
}
public void setUpViewModel_cats(){
viewModel.getAllCats().observe(this, new Observer<List<CatsTable>>() {
@Override
public void onChanged(@Nullable List<CatsTable> catsTables) {
adapter.setCat_list((ArrayList<CatsTable>) catsTables);
}
});
}
// Add
public void insertDog() {
String dogName = String.valueOf(et_addDogName.getText()).trim();
DogsTable obj_dog = new DogsTable(dogName);
viewModel.insertDog(obj_dog);
Toast.makeText(this, "Dog Added", Toast.LENGTH_SHORT).show();
}
public void insertCat() {
String catName = String.valueOf(et_addCatName.getText());
CatsTable obj_cat = new CatsTable(catName);
viewModel.insertCat(obj_cat);
Toast.makeText(this, "cat Added", Toast.LENGTH_SHORT).show();
}
// Delete
public void swapToDelete_dog() {
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(final RecyclerView.ViewHolder viewHolder, int direction) {
List<DogsTable> dog_pos = adapter.getDog_list();
viewModel.deleteDog(dog_pos.get(viewHolder.getAdapterPosition()));
}
}
).attachToRecyclerView(recyclerView);
}
public void swapToDelete_cat() {
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int item_id = item.getItemId();
if (item_id == R.id.menu_add) {
Intent in = new Intent(this, Add.class);
startActivity(in);
}
return super.onOptionsItemSelected(item);
}
@Override
public void onItemClickListener(int pet_id) {
}
}
MainActivityAdapter.java
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/addDogNameET_xml"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:hint="add Dog name" />
<Button
android:id="@+id/AddDog_btn_xml"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="add" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/addCatNameET_xml"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:hint="add Cat name" />
<Button
android:id="@+id/AddCat_btn_xml"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="add" />
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="MissingConstraints" />
</LinearLayout>
activity_main_adapter.xml
public class MainActivityAdapter extends RecyclerView.Adapter<MainActivityAdapter.MyViewHolder> {
Context mContext;
ArrayList<DogsTable> dog_list;
ArrayList<CatsTable> cat_list;
ItemClickListener mItemClickListener;
public MainActivityAdapter(Context context , ItemClickListener itemClickListener) {
this.mContext = context;
this.mItemClickListener = itemClickListener;
}
public interface ItemClickListener {
void onItemClickListener(int pet_id);
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(mContext).inflate(R.layout.activity_main_adapter, viewGroup, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
DogsTable dog_pos = dog_list.get(position);
// CatsTable catsTable = cat_list.get(position);
holder.dogName.setText(String.valueOf(dog_pos.getDogName()));
// holder.catName.setText(String.valueOf(catsTable.getCatName()));
}
@Override
public int getItemCount() {
if (dog_list == null ) {
return 0;
} else {
return dog_list.size();
}
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener , ItemClickListener {
TextView dogName;
TextView catName;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
dogName = itemView.findViewById(R.id.dogName_xml);
catName = itemView.findViewById(R.id.catName_xml);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
int pet_id = dog_list.get(getAdapterPosition()).getDogs_id();
mItemClickListener.onItemClickListener(pet_id);
}
@Override
public void onItemClickListener(int pet_id) {
int pos = dog_list.get(getAdapterPosition()).getDogs_id();
mItemClickListener.onItemClickListener(pet_id);
}
}
public void setDog_list(ArrayList<DogsTable> dog_list) {
this.dog_list = dog_list;
notifyDataSetChanged();
}
public ArrayList<DogsTable> getDog_list() {
return dog_list;
}
public void setCat_list(ArrayList<CatsTable> cat_list) {
this.cat_list = cat_list;
}
}
答案 0 :(得分:2)
为支持不同的视图类型,RecyclerView.Adapter
提供了一种有用的方法int getItemViewType(int position)
:
出于回收视图的目的,返回该项目的视图类型。
此方法的默认实现返回0,并假设适配器具有单一视图类型。与ListView适配器不同,类型不必是连续的。考虑使用id资源来唯一标识项目视图类型。
然后,在onCreateViewHolder
中,您可以看到第二个参数是int viewType
,它来自方法int getItemViewType(int position)
。基于此,您可以实例化所需的ViewHolder
,例如DogViewHolder
或CatViewHolder
。
但是在单个适配器中存储多个视图模型并定义应实际实例化的ViewHolder
类型呢?这是两种最受欢迎的方法:
getItemViewType
方法定义自定义逻辑,例如所有奇数都将出现在狗的列表中,偶数将出现在猫的列表中(或其他任何方法,但是请注意,您将不得不处理不同列表的大小和所需的所有视图类型)。另外,getItemsCount
应该适当地被覆盖(return list1.size() + list2.size + ... + listN.size();
)将所有视图模型放在一个列表中,并执行某种属性检查:要么是某些属性,要么是类型本身(出于可伸缩性原因不建议使用)。然后您的代码将如下所示:
public int getItemViewType(int position) {
CommonParentForUpcasting item = items.get(position);
if (item instanceOf Dog) { // or something like item.type == Animal.CAT
return R.id.holder_dog;
} else {
return R.id.holder_cat;
}
}
如果您想提出第二种解决方案,请this solution should suit you well。 另外,请确保选中此StackOverflow answer。