如何在RecyclerView中显示多个对象类型?

时间:2019-02-25 09:05:25

标签: android android-recyclerview

我正在使用房间数据库创建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中所示。
Image of the recyclerview explain the first problem

2-如何解决getItemCount()方法?我不知道如何返回两个不同的对象cat_list.size();dog_list.size();

3-还是在onBindViewHolder()方法中,我不知道如何获取cat_list值以在UI中显示它们?

4-另一个问题是swapToDelete()的{​​{1}}方法中,我可以获取删除它的狗id,但是我无法获取删除它的cat id,我该如何获取猫ID ?

5-如何显示(dog1,dog2,dog3)为第一张图片所示? (我将值手动插入到第一张图像中只是为了显示我要如何显示它们)

first image,

MainActivity.class

This is actually how it displayed

我的代码

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;
}
}

1 个答案:

答案 0 :(得分:2)

为支持不同的视图类型,RecyclerView.Adapter提供了一种有用的方法int getItemViewType(int position)

  

出于回收视图的目的,返回该项目的视图类型。

     

此方法的默认实现返回0,并假设适配器具有单一视图类型。与ListView适配器不同,类型不必是连续的。考虑使用id资源来唯一标识项目视图类型。

然后,在onCreateViewHolder中,您可以看到第二个参数是int viewType,它来自方法int getItemViewType(int position)。基于此,您可以实例化所需的ViewHolder,例如DogViewHolderCatViewHolder

但是在单个适配器中存储多个视图模型并定义应实际实例化的ViewHolder类型呢?这是两种最受欢迎​​的方法:

  1. 为多种类型声明多个容器,并为getItemViewType方法定义自定义逻辑,例如所有奇数都将出现在狗的列表中,偶数将出现在猫的列表中(或其他任何方法,但是请注意,您将不得不处理不同列表的大小和所需的所有视图类型)。另外,getItemsCount应该适当地被覆盖(return list1.size() + list2.size + ... + listN.size();
  2. 将所有视图模型放在一个列表中,并执行某种属性检查:要么是某些属性,要么是类型本身(出于可伸缩性原因不建议使用)。然后您的代码将如下所示:

    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