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
    @Override
    public 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);
    }

    @Override
    public 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);
    }


    @Override
    public 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
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_rv, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public 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);
    }


    @Override
    public 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 复制代码
<?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:
XML 复制代码
public class ViewTypeListAdapter extends RecyclerView.Adapter<ViewTypeListAdapter.ViewHolder> {
    private final List<View> viewList;

    public ViewTypeListAdapter(List<View> views) {
        this.viewList = views;
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new ViewHolder(viewList.get(viewType));
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

    }


    @Override
    public 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

相关推荐
我是好小孩2 分钟前
【Android】Binder 原理初探:理解 Android 进程通信机制
android·gitee·binder
-指短琴长-31 分钟前
ProtoBuf速成【基于C++讲解】
android·java·c++
下位子34 分钟前
『OpenGL学习滤镜相机』- Day4: 纹理贴图基础
android·opengl
2501_9159090642 分钟前
iOS 发布 App 全流程指南,从签名打包到开心上架(Appuploader)跨平台免 Mac 上传实战
android·macos·ios·小程序·uni-app·cocoa·iphone
Kapaseker43 分钟前
在 Compose 中使用 SurfaceView
android·kotlin
你不是我我1 小时前
【Java 开发日记】设计模式了解吗,知道什么是饿汉式和懒汉式吗?
android·java·开发语言
HahaGiver6662 小时前
Unity与Android原生交互开发入门篇 - 打开Android的设置
android·java·unity·游戏引擎·android studio
冬天vs不冷2 小时前
Java基础(十五):注解(Annotation)详解
android·java·python
星释11 小时前
二级等保实战:MySQL安全加固
android·mysql·安全