具有多个布局的RecyclerView,插入/删除功能和单击侦听器 [英] RecyclerView with multiple layouts, insert/delete function and click listener
问题描述
我正在开发一个工作估算应用程序,该应用程序将信息存储在房间数据库中,并通过RecyclerView保存对它的引用,用户可以使用该视图访问数据并根据需要进行更改.
I am developing a job estimation app which stores information in a room database and holds a reference to it via a RecyclerView which user can use to access the data and make changes if needed.
我正在通过Fragment内带有Observer方法的视图模型使用Live Data检索对信息的引用.用户填写表单并按保存按钮后,此信息将存储在数据库中.
I am retrieving a reference to the information using Live Data via a view model with Observer method inside a Fragment. This information is stored in a database when the user completes a form and presses the save button.
目前,我已经开发了两个标准适配器,它们具有不同的数据集和单独的布局.
Currently I have developed two standard adapters, with different data sets and separate layouts.
public class HallDetailAdapter extends RecyclerView.Adapter<HallDetailAdapter.myViewHolder> {
private List<HallDetails> mHallDetails;
public void setHallDetails(final List<HallDetails> hallDetails) {
this.mHallDetails = hallDetails;
notifyDataSetChanged();
}
@NonNull
@Override
public HallDetailAdapter.myViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_design,parent,false);
return new myViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final HallDetailAdapter.myViewHolder holder, final int position) {
if(mHallDetails != null){
HallDetails details = mHallDetails.get(position);
holder.mTextView.setText(details.getName());
}else{
holder.mTextView.setText("No Data Entry");
}
}
@Override
public int getItemCount() {
if(mHallDetails != null)
return mHallDetails.size();
else return 0;
}
class myViewHolder extends RecyclerView.ViewHolder{
private TextView mTextView;
public myViewHolder(@NonNull final View itemView) {
super(itemView);
mTextView = itemView.findViewById(R.id.display_name);
}
}
}
public class RoomDetailsAdapter extends RecyclerView.Adapter<RoomDetailsAdapter.myViewHolder> {
private List<RoomDetails> mRoomDetails;
public void setRoomDetails(final List<RoomDetails> roomDetails) {
this.mRoomDetails = roomDetails;
notifyDataSetChanged();
}
@NonNull
@Override
public RoomDetailsAdapter.myViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_design2,parent,false);
return new myViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final RoomDetailsAdapter.myViewHolder holder, final int position) {
if(mRoomDetails != null) {
RoomDetails details = mRoomDetails.get(position);
holder.mTextView.setText(details.getName());
}else{
holder.mTextView.setText("No data entry");
}
}
@Override
public int getItemCount() {
if(mRoomDetails != null){
return mRoomDetails.size();
}else return 0;
}
public class myViewHolder extends RecyclerView.ViewHolder{
private TextView mTextView;
public myViewHolder(@NonNull final View itemView) {
super(itemView);
mTextView = itemView.findViewById(R.id.display_roomDetails);
}
}
在Fragment内调用的更改方法:
On change methods called inside Fragment:
dataViewModel.getName().observe(getActivity(), new Observer<List<HallDetails>>() {
@Override
public void onChanged(final List<HallDetails> hallDetails) {
if(hallDetails != null) {
hallDetailAdapter.setHallDetails(hallDetails);
}
}
});
dataViewModel.getGetName2().observe(getActivity(), new Observer<List<RoomDetails>>() {
@Override
public void onChanged(final List<RoomDetails> roomDetails) {
if(roomDetails != null) {
roomDetailsAdapter.setRoomDetails(roomDetails);
}
}
});
我的问题是,如何在遵守这些功能的同时将多个布局集成到RecyclerView中?
My question is, how do I integrate multiple layouts to the RecyclerView while also adhering to these functionalities:
- 在回收者视图中添加和删除项目
- 为每个显示的项目设置一个点击侦听器
- 在相应的布局内显示数据,该数据已在适配器内部引用,并通过实时数据进行了更新.
谢谢您的帮助!
推荐答案
要在单个RecyclerView中显示多个布局,您必须在recyclerview适配器类中使用多个Viewholder.
例如,一个视图用于显示数据,另一个视图用于显示数据项之间的Admob/facebook广告.因此,您的适配器类如下所示代码.
For Example One view is use to Display Your Data and another view is use to Display Admob/facebook Ad between the data Item.So your Adapter Class look like Below Code.
public class StatusImageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<String> images;
private String path;
private Context context;
OnIteamClickListner listner;
private String status;
private static final int AD_VIEW_HOLDER = 0;
private static final int CONTENT_VIEW_HOLDER = 1;
public StatusImageAdapter(Context context, ArrayList<String> images, String path, OnIteamClickListner listner, String status) {
this.images = images;
this.path = path;
this.context = context;
this.listner = listner;
this.status = status;
}
public interface OnIteamClickListner {
void onIteamClick(View view, String action, int position, String path);
}
@Override
public int getItemViewType(int position) {
if (position % Const.ITEMS_PER_AD == 0 && position>1)
return AD_VIEW_HOLDER;
return CONTENT_VIEW_HOLDER;
}
@Override
public int getItemCount() {
return images.size();
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
switch (viewType) {
case AD_VIEW_HOLDER:
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.admob_banner_row_item, parent, false);
return new AdViewHolder(itemView);
case CONTENT_VIEW_HOLDER:
// fall through
default:
View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.image_item, null);
return new ContentViewHolder(itemLayoutView);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
int viewType = getItemViewType(position);
switch (viewType) {
case AD_VIEW_HOLDER:
AdViewHolder adViewHolder= (AdViewHolder) holder;
adViewHolder.adView.setVisibility(View.GONE);
CommonMethods.loadAd(context,adViewHolder.adView);
break;
case CONTENT_VIEW_HOLDER:
ContentViewHolder contentViewHolder = (ContentViewHolder) holder;
Bitmap bitmap = BitmapFactory.decodeFile( images.get(position));
contentViewHolder.imageView.setImageBitmap(bitmap);
if (status.equals(Const.ONLINE)) {
contentViewHolder.img_download.setBackgroundResource(R.drawable.ic_download_black);
}
if (status.equals(Const.OFLINE)) {
contentViewHolder.img_download.setBackgroundResource(R.drawable.ic_delete);
}
contentViewHolder.imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listner.onIteamClick(view, "View", position, path);
}
});
contentViewHolder.img_view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listner.onIteamClick(view, "QuickView", position, path);
}
});
contentViewHolder.img_download.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (status.equals(Const.ONLINE)) {
listner.onIteamClick(view, "Download", position, path);
}
if (status.equals(Const.OFLINE)) {
listner.onIteamClick(view, "Delete", position, path);
}
}
});
contentViewHolder.img_share.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listner.onIteamClick(view, "Share", position, path);
}
});
}
}
private class AdViewHolder extends RecyclerView.ViewHolder {
AdView adView;
public AdViewHolder(View itemView) {
super(itemView);
adView=itemView.findViewById(R.id.adView);
}
}
private class ContentViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
ImageView img_share, img_download, img_view;
public ContentViewHolder(View itemLayoutView) {
super(itemLayoutView);
imageView = itemView.findViewById(R.id.statusItem_imageView);
img_share = itemView.findViewById(R.id.img_share);
img_download = itemView.findViewById(R.id.img_download);
img_view = itemView.findViewById(R.id.img_view);
}
}
}
从您的活动课程文件中调用此适配器.
StatusImageAdapter statusImageAdapter = new StatusImageAdapter(context, imageFiles, hiddenpath.getAbsolutePath(), this, Const.ONLINE);
这篇关于具有多个布局的RecyclerView,插入/删除功能和单击侦听器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!