Android RecyclerView展示List<View> Adapter的数据源使用View
Android不推荐使用View作为 Recyclerview.Adapter的数据源;弊端像回收或复用就不多说了,要展示List<View>肯定是有原由的!
方式一、FrameLayout.addView:
public class ViewListAdapter extends RecyclerView.Adapter<ViewListAdapter.ViewHolder> {private final List<View> viewList;public ViewListAdapter(List<View> views) {this.viewList = views;}@NonNull@Overridepublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {// 使用 FrameLayout 作为容器,避免布局嵌套问题FrameLayout container = new FrameLayout(parent.getContext());container.setLayoutParams(new RecyclerView.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,FrameLayout.LayoutParams.WRAP_CONTENT));return new ViewHolder(container);}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {View currentView = viewList.get(position);// 移除容器中已有的 View(避免复用冲突)holder.container.removeAllViews();if(currentView.getParent() != null){// 移除需要添加View的父布局(避免复用冲突)((ViewGroup)currentView.getParent()).removeView(currentView);}// 确保 View 有布局参数if (currentView.getLayoutParams() == null) {FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,FrameLayout.LayoutParams.WRAP_CONTENT);currentView.setLayoutParams(params);}holder.container.addView(currentView);}@Overridepublic int getItemCount() {return viewList.size();}public static class ViewHolder extends RecyclerView.ViewHolder {FrameLayout container;public ViewHolder(View itemView) {super(itemView);container = (FrameLayout) itemView;}}
}
方式二、XML文件addView:
public class ViewAdapter extends RecyclerView.Adapter<ViewAdapter.ViewHolder> {private final List<View> viewList;public ViewAdapter(List<View> views) {this.viewList = views;}@NonNull@Overridepublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_rv, parent, false);return new ViewHolder(view);}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {View currentView = viewList.get(position);// 移除容器中已有的 View(避免复用冲突)holder.container.removeAllViews();if(currentView.getParent() != null){// 移除需要添加View的父布局(避免复用冲突)((ViewGroup)currentView.getParent()).removeView(currentView);}holder.container.addView(currentView);}@Overridepublic int getItemCount() {return viewList.size();}public static class ViewHolder extends RecyclerView.ViewHolder {FrameLayout container;public ViewHolder(View itemView) {super(itemView);container = (FrameLayout) itemView;}}
}
R.layout.layout_rv
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="300dp"android:padding="10dp"android:layout_height="300dp">
</FrameLayout>
方式三、viewType代替position:
public class ViewTypeListAdapter extends RecyclerView.Adapter<ViewTypeListAdapter.ViewHolder> {private final List<View> viewList;public ViewTypeListAdapter(List<View> views) {this.viewList = views;}@Overridepublic int getItemViewType(int position) {return position;}@NonNull@Overridepublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {return new ViewHolder(viewList.get(viewType));}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {}@Overridepublic int getItemCount() {return viewList.size();}public static class ViewHolder extends RecyclerView.ViewHolder {public ViewHolder(View itemView) {super(itemView);}}
}
方式三不推荐,notifyDataSetChanged等刷新会有问题;
java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling androidx.recyclerview.widget.RecyclerView
IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
没必要使用RecyclerView时,可以使用 ScrollView + LinearLayout + addView