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

一、最终效果:

二、工程结构框架:

三、核心实现:

(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

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

  • 0
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
实现这个功能需要用到uniapp的组件和事件。 首先,在页面中添加一个textarea组件,用于用户输入评论内容: ``` <template> <view> <textarea class="comment-input" v-model="comment" placeholder="请输入评论内容" @focus="showInputBox" ></textarea> </view> <view :class="['input-box', {show: showBox}]"> <textarea class="input-textarea" v-model="comment" placeholder="请输入评论内容" @blur="hideInputBox" ></textarea> </view> </template> ``` 在组件中,使用v-model绑定comment变量,用于存储用户输入的评论内容。同时,在textarea的focus事件中调用showInputBox方法,显示底部的输入框。 ``` <script> export default { data() { return { comment: '', showBox: false } }, methods: { showInputBox() { this.showBox = true }, hideInputBox() { this.showBox = false } } } </script> ``` 在showInputBox方法中,将showBox变量设置为true,用于显示底部的输入框。在hideInputBox方法中,将showBox变量设置为false,用于隐藏底部的输入框。 最后,在底部的输入框中也添加一个textarea组件,并在blur事件中调用hideInputBox方法,用于隐藏输入框。 同时,需要添加CSS样式,用于控制底部输入框的显示和隐藏: ``` <style> .comment-input { height: 100px; border: none; outline: none; resize: none; font-size: 28rpx; padding: 20rpx; } .input-box { position: fixed; bottom: 0; left: 0; right: 0; height: 200rpx; background-color: #fff; transform: translateY(200rpx); transition: transform 0.3s ease-in-out; } .input-box.show { transform: translateY(0); } .input-textarea { height: 160rpx; border: none; outline: none; resize: none; font-size: 28rpx; padding: 20rpx; } </style> ``` 这样,就实现仿照小红书评论界面的功能,点击输入框时,底部弹出输入框和键盘。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wave12_mp

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

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

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

打赏作者

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

抵扣说明:

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

余额充值