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

相关推荐
BoomHe19 分钟前
Now in Android 架构模式全面分析
android·android jetpack
二流小码农8 小时前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少8 小时前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker8 小时前
一杯美式搞定 Kotlin 空安全
android·kotlin
三少爷的鞋9 小时前
Android 协程时代,Handler 应该退休了吗?
android
火柴就是我1 天前
让我们实现一个更好看的内部阴影按钮
android·flutter
砖厂小工1 天前
用 GLM + OpenClaw 打造你的 AI PR Review Agent — 让龙虾帮你审代码
android·github
张拭心1 天前
春节后,有些公司明确要求 AI 经验了
android·前端·人工智能
张拭心1 天前
Android 17 来了!新特性介绍与适配建议
android·前端
Kapaseker1 天前
Compose 进阶—巧用 GraphicsLayer
android·kotlin