使用RecyclerView实现瀑布流,仿照小红书,解决顶部留白、卡顿等问题

本文介绍了一种使用RecyclerView实现瀑布流布局的方法,并详细讲解了如何自定义适配器以支持不同类型的视图项,包括图片的轻量级圆角处理、解决拖动过程中顶部空白的问题及优化加载效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、最终效果:

二、工程结构框架:

三、核心实现:

(1)、实现RecyclerView控件的适配器类

主要就是实现下面三个函数的重载:

 @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(mContext).inflate(R.layout.item_layout, parent, false);
        return new NormalHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        NormalHolder normalHolder = (NormalHolder) holder;
        normalHolder.mTitle.setText(mDatas.get(position).title);
        normalHolder.mUserName.setText(mDatas.get(position).userName);
        normalHolder.mHits.setText(mDatas.get(position).hits.toString());
        Class drawable = R.drawable.class;
        Field field = null;
        try {
            field = R.mipmap.class.getDeclaredField(mDatas.get(position).mainPic);
            int mainPicId = field.getInt(field.getName());

            WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
            DisplayMetrics dm = new DisplayMetrics();
            wm.getDefaultDisplay().getMetrics(dm);
            int width = dm.widthPixels;         // 屏幕宽度(像素)
            int height = dm.heightPixels;       // 屏幕高度(像素)
            float density = dm.density;         // 屏幕密度(0.75 / 1.0 / 1.5)
            int densityDpi = dm.densityDpi;     // 屏幕密度dpi(120 / 160 / 240)
            // 屏幕宽度算法:屏幕宽度(像素)/屏幕密度
            int screenWidth = (int) (width / density);  // 屏幕宽度(dp)
            int screenHeight = (int) (height / density);// 屏幕高度(dp)

            ViewGroup.LayoutParams lp = normalHolder.mMainPic.getLayoutParams();
            int wArea = (int)((screenWidth - 30) / 2  * density);   // 20dp是布局文件设定的边距
            Bitmap bmp = BitmapFactory.decodeResource(mContext.getResources(), mainPicId);
            int wBitmap = bmp.getWidth();
            int hBitmap = bmp.getHeight();
            double dRate = wArea / (double)wBitmap;
            int hArea = (int)(hBitmap * dRate);
            lp.width = wArea;
            lp.height = hArea;
            normalHolder.mMainPic.setLayoutParams(lp);
            normalHolder.mMainPic.setMaxHeight(wArea * 5);
            normalHolder.mMainPic.setImageResource(mainPicId);

            field = R.drawable.class.getDeclaredField(mDatas.get(position).headImage);
            int headImageId = field.getInt(field.getName());
            normalHolder.mHeadImg.setImageResource(headImageId);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }

    }

    @Override
    public int getItemCount() {
        return mDatas.size();
    }

(2)、应用瀑布流来布局

 generateDatas();   // 产生模拟数据
        RecyclerView mRv = findViewById(R.id.userList);

        // 布局
        StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
        layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE); //防止item 交换位置
        mRv.setLayoutManager(layoutManager);

(3)、放置拖动过程中顶部出现空白

   mRv.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                //防止第一行到顶部有空白区域
                layoutManager.invalidateSpanAssignments();
            }
        });

(4)、图片实现了轻量级的圆角处理,可以实现部分圆角化。

由类NiceImageView来实现图片圆角。

(5)、实现了放置item位置发生变化,同时将图片资源放到midmap里,有效放置拖动过程中的卡顿。
 

四、源码下载:

可以去这里下载:https://www.kbase12.com/android/doc/detail?id=ef594c604cf9498a8b73609e6665d3ae

欢迎有兴趣的朋友一起交流。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wave12_mp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值