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

相关推荐
JMchen1231 小时前
Android后台服务与网络保活:WorkManager的实战应用
android·java·网络·kotlin·php·android-studio
crmscs2 小时前
剪映永久解锁版/电脑版永久会员VIP/安卓SVIP手机永久版下载
android·智能手机·电脑
localbob2 小时前
杀戮尖塔 v6 MOD整合版(Slay the Spire)安卓+PC端免安装中文版分享 卡牌肉鸽神作!杀戮尖塔中文版,电脑和手机都能玩!杀戮尖塔.exe 杀戮尖塔.apk
android·杀戮尖塔apk·杀戮尖塔exe·游戏分享
机建狂魔2 小时前
手机秒变电影机:Blackmagic Camera + LUT滤镜包的专业级视频解决方案
android·拍照·摄影·lut滤镜·拍摄·摄像·录像
hudawei9962 小时前
flutter和Android动画的对比
android·flutter·动画
lxysbly4 小时前
md模拟器安卓版带金手指2026
android
儿歌八万首5 小时前
硬核春节:用 Compose 打造“赛博鞭炮”
android·kotlin·compose·春节
消失的旧时光-19437 小时前
从 Kotlin 到 Dart:为什么 sealed 是处理「多种返回结果」的最佳方式?
android·开发语言·flutter·架构·kotlin·sealed
Jinkxs7 小时前
Gradle - 与Groovy/Kotlin DSL对比 构建脚本语言选择指南
android·开发语言·kotlin
&有梦想的咸鱼&7 小时前
Kotlin委托机制的底层实现深度解析(74)
android·开发语言·kotlin