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

相关推荐
liang_jy15 小时前
Android SparseArray
android·源码
liang_jy16 小时前
Activity 启动流程扩展篇(一)—— startActivityInner 任务决策全解析
android·源码
NPE~17 小时前
[App逆向]脱壳实战
android·教程·逆向·android逆向·逆向分析
木易 士心17 小时前
别再只会用 drawCircle 了!一文搞懂 Android Canvas 底层机制
android
AtOR CUES19 小时前
MySQL——表操作及查询
android·mysql·adb
怣疯knight20 小时前
安卓App无法增加自定义图片作为图标功能
android
jinanwuhuaguo21 小时前
OpenClaw联邦之心——从孤岛记忆到硅基集体潜意识的拓扑学革命(第二十三篇)
android·人工智能·kotlin·拓扑学·openclaw
Gary Studio1 天前
安卓HAL C++基础-命名域
android
诸神黄昏EX1 天前
Android Google XTS
android
eSsO KERF1 天前
MySQL Workbench菜单汉化为中文
android·数据库·mysql