[Android]自由添加Head和Foot对RecyclerView的Adapter

1.RecyclerView在adapter基础上添加headview拓展 立即下载

该Adapter能达到给RecyclerView自由添加Head和View的目的,且添加的Head和Foot不受LayouManager干扰,代码如下:

public class BaseHeaderAndFooterAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final int BASE_ITEM_TYPE_HEADER = 100000;
    private static final int BASE_ITEM_TYPE_FOOTER = 200000;

    private SparseArrayCompat<View> mHeaderViews = new SparseArrayCompat<>();
    private SparseArrayCompat<View> mFootViews = new SparseArrayCompat<>();

    private RecyclerView.Adapter mInnerAdapter;

    public BaseHeaderAndFooterAdapter(RecyclerView.Adapter adapter) {
        mInnerAdapter = adapter;
    }

    private boolean isHeaderViewPos(int position) {
        return position < getHeadersCount();
    }

    private boolean isFooterViewPos(int position) {
        return position >= getHeadersCount() + getRealItemCount();
    }


    public void addHeaderView(View view) {
        mHeaderViews.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER, view);
    }

    public void addFootView(View view) {
        mFootViews.put(mFootViews.size() + BASE_ITEM_TYPE_FOOTER, view);
    }

    public int getHeadersCount() {
        return mHeaderViews.size();
    }

    public int getFootersCount() {
        return mFootViews.size();
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (mHeaderViews.get(viewType) != null) {

            ViewHolder holder = ViewHolder.createViewHolder(parent.getContext(), mHeaderViews.get(viewType));
            return holder;

        } else if (mFootViews.get(viewType) != null) {
            ViewHolder holder = ViewHolder.createViewHolder(parent.getContext(), mFootViews.get(viewType));
            return holder;
        }
        return mInnerAdapter.onCreateViewHolder(parent, viewType);
    }

    @Override
    public int getItemViewType(int position) {
        if (isHeaderViewPos(position)) {
            return mHeaderViews.keyAt(position);
        } else if (isFooterViewPos(position)) {
            return mFootViews.keyAt(position - getHeadersCount() - getRealItemCount());
        }
        return mInnerAdapter.getItemViewType(position - getHeadersCount());
    }

    private int getRealItemCount() {
        return mInnerAdapter.getItemCount();
    }


    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (isHeaderViewPos(position)) {
            return;
        }
        if (isFooterViewPos(position)) {
            return;
        }
        mInnerAdapter.onBindViewHolder(holder, position - getHeadersCount());
    }

    @Override
    public int getItemCount() {
        return getHeadersCount() + getFootersCount() + getRealItemCount();
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        WrapperUtils.onAttachedToRecyclerView(mInnerAdapter, recyclerView, new WrapperUtils.SpanSizeCallback() {
            @Override
            public int getSpanSize(GridLayoutManager layoutManager, GridLayoutManager.SpanSizeLookup oldLookup, int position) {
                int viewType = getItemViewType(position);
                if (mHeaderViews.get(viewType) != null) {
                    return layoutManager.getSpanCount();
                } else if (mFootViews.get(viewType) != null) {
                    return layoutManager.getSpanCount();
                }
                if (oldLookup != null)
                    return oldLookup.getSpanSize(position);
                return 1;
            }
        });
    }

    @Override
    public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
        mInnerAdapter.onViewAttachedToWindow(holder);
        int position = holder.getLayoutPosition();
        if (isHeaderViewPos(position) || isFooterViewPos(position)) {
            WrapperUtils.setFullSpan(holder);
        }
    }


    public static class ViewHolder extends RecyclerView.ViewHolder
    {
        private SparseArray<View> mViews;
        private View mConvertView;
        private Context mContext;

        public ViewHolder(Context context, View itemView)
        {
            super(itemView);
            mContext = context;
            mConvertView = itemView;
            mViews = new SparseArray<View>();
        }


        public static ViewHolder createViewHolder(Context context, View itemView)
        {
            ViewHolder holder = new ViewHolder(context, itemView);
            return holder;
        }

        public static ViewHolder createViewHolder(Context context,
                                                  ViewGroup parent, int layoutId)
        {
            View itemView = LayoutInflater.from(context).inflate(layoutId, parent,
                    false);
            ViewHolder holder = new ViewHolder(context, itemView);
            return holder;
        }

        /**
         * 通过viewId获取控件
         *
         * @param viewId
         * @return
         */
        public <T extends View> T getView(int viewId)
        {
            View view = mViews.get(viewId);
            if (view == null)
            {
                view = mConvertView.findViewById(viewId);
                mViews.put(viewId, view);
            }
            return (T) view;
        }

        public View getConvertView()
        {
            return mConvertView;
        }




        /****以下为辅助方法*****/

        /**
         * 设置TextView的值
         *
         * @param viewId
         * @param text
         * @return
         */
        public ViewHolder setText(int viewId, String text)
        {
            TextView tv = getView(viewId);
            tv.setText(text);
            return this;
        }

        public ViewHolder setImageResource(int viewId, int resId)
        {
            ImageView view = getView(viewId);
            view.setImageResource(resId);
            return this;
        }

        public ViewHolder setImageBitmap(int viewId, Bitmap bitmap)
        {
            ImageView view = getView(viewId);
            view.setImageBitmap(bitmap);
            return this;
        }

        public ViewHolder setImageDrawable(int viewId, Drawable drawable)
        {
            ImageView view = getView(viewId);
            view.setImageDrawable(drawable);
            return this;
        }

        public ViewHolder setBackgroundColor(int viewId, int color)
        {
            View view = getView(viewId);
            view.setBackgroundColor(color);
            return this;
        }

        public ViewHolder setBackgroundRes(int viewId, int backgroundRes)
        {
            View view = getView(viewId);
            view.setBackgroundResource(backgroundRes);
            return this;
        }

        public ViewHolder setTextColor(int viewId, int textColor)
        {
            TextView view = getView(viewId);
            view.setTextColor(textColor);
            return this;
        }

        public ViewHolder setTextColorRes(int viewId, int textColorRes)
        {
            TextView view = getView(viewId);
            view.setTextColor(mContext.getResources().getColor(textColorRes));
            return this;
        }

        @SuppressLint("NewApi")
        public ViewHolder setAlpha(int viewId, float value)
        {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
            {
                getView(viewId).setAlpha(value);
            } else
            {
                // Pre-honeycomb hack to set Alpha value
                AlphaAnimation alpha = new AlphaAnimation(value, value);
                alpha.setDuration(0);
                alpha.setFillAfter(true);
                getView(viewId).startAnimation(alpha);
            }
            return this;
        }

        public ViewHolder setVisible(int viewId, boolean visible)
        {
            View view = getView(viewId);
            view.setVisibility(visible ? View.VISIBLE : View.GONE);
            return this;
        }

        public ViewHolder linkify(int viewId)
        {
            TextView view = getView(viewId);
            Linkify.addLinks(view, Linkify.ALL);
            return this;
        }

        public ViewHolder setTypeface(Typeface typeface, int... viewIds)
        {
            for (int viewId : viewIds)
            {
                TextView view = getView(viewId);
                view.setTypeface(typeface);
                view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
            }
            return this;
        }

        public ViewHolder setProgress(int viewId, int progress)
        {
            ProgressBar view = getView(viewId);
            view.setProgress(progress);
            return this;
        }

        public ViewHolder setProgress(int viewId, int progress, int max)
        {
            ProgressBar view = getView(viewId);
            view.setMax(max);
            view.setProgress(progress);
            return this;
        }

        public ViewHolder setMax(int viewId, int max)
        {
            ProgressBar view = getView(viewId);
            view.setMax(max);
            return this;
        }

        public ViewHolder setRating(int viewId, float rating)
        {
            RatingBar view = getView(viewId);
            view.setRating(rating);
            return this;
        }

        public ViewHolder setRating(int viewId, float rating, int max)
        {
            RatingBar view = getView(viewId);
            view.setMax(max);
            view.setRating(rating);
            return this;
        }

        public ViewHolder setTag(int viewId, Object tag)
        {
            View view = getView(viewId);
            view.setTag(tag);
            return this;
        }

        public ViewHolder setTag(int viewId, int key, Object tag)
        {
            View view = getView(viewId);
            view.setTag(key, tag);
            return this;
        }

        public ViewHolder setChecked(int viewId, boolean checked)
        {
            Checkable view = (Checkable) getView(viewId);
            view.setChecked(checked);
            return this;
        }

        /**
         * 关于事件的
         */
        public ViewHolder setOnClickListener(int viewId,
                                             View.OnClickListener listener)
        {
            View view = getView(viewId);
            view.setOnClickListener(listener);
            return this;
        }

        public ViewHolder setOnTouchListener(int viewId,
                                             View.OnTouchListener listener)
        {
            View view = getView(viewId);
            view.setOnTouchListener(listener);
            return this;
        }

        public ViewHolder setOnLongClickListener(int viewId,
                                                 View.OnLongClickListener listener)
        {
            View view = getView(viewId);
            view.setOnLongClickListener(listener);
            return this;
        }


    }

    /**
     * Created by zhy on 16/6/28.
     */
    public static class WrapperUtils
    {
        public interface SpanSizeCallback
        {
            int getSpanSize(GridLayoutManager layoutManager, GridLayoutManager.SpanSizeLookup oldLookup, int position);
        }

        public static void onAttachedToRecyclerView(RecyclerView.Adapter innerAdapter, RecyclerView recyclerView, final SpanSizeCallback callback)
        {
            innerAdapter.onAttachedToRecyclerView(recyclerView);

            RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
            if (layoutManager instanceof GridLayoutManager)
            {
                final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
                final GridLayoutManager.SpanSizeLookup spanSizeLookup = gridLayoutManager.getSpanSizeLookup();

                gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup()
                {
                    @Override
                    public int getSpanSize(int position)
                    {
                        return callback.getSpanSize(gridLayoutManager, spanSizeLookup, position);
                    }
                });
                gridLayoutManager.setSpanCount(gridLayoutManager.getSpanCount());
            }
        }

        public static void setFullSpan(RecyclerView.ViewHolder holder)
        {
            ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();

            if (lp != null
                    && lp instanceof StaggeredGridLayoutManager.LayoutParams)
            {

                StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;

                p.setFullSpan(true);
            }
        }
    }
}

使用方法如下:

RecyclerView.Adapter homeExpertsAdapter = new HomeExpertsAdapter(new ArrayList<ResultBean>());
BaseHeaderAndFooterAdapter baseHeaderAndFooterAdapter = new BaseHeaderAndFooterAdapter(homeExpertsAdapter);

TextView textView = new TextView(getContext());
textView.setText("Header_1");
baseHeaderAndFooterAdapter.addHeaderView(textView);

recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 4));
recyclerView.setAdapter(baseHeaderAndFooterAdapter);
封装 RecyclerViewAdapter ,可以不用写 ViewHolder, 支持添加 head 和 foot, 支持 head 和 foot 的点击事件 博客地址:http://blog.csdn.net/oaitan/article/details/51723272 RecyclerView 虽然可塑性很高, 而且使用起来确实很方便,但是它不像 ListView 一样可以随意添加头部和尾部, 以前用 listview 的时候随意添加头部和尾部确实方便了不少,但是 RecyclerView 本身是不支持这样写得, 那只能我们自己去写一个。 RecyclerView 可以通过 getItemViewType() 去区分不同的布局, 很明显从这里下手是正确的选择, 但是每个 Adapter 都写大量相同的代码这样对于一个有着代码洁癖和强迫症的人 (其实指的就是我) 很明显是打心里抵触的。于是乎去封装一个 BaseRecyclerViewAdapter. 使得我们可以在编写的过程中省却大量的重复代码。 立即下载

相关推荐

Android RecyclerView添加FootView和HeadView

主要介绍了Android RecyclerView添加FootView和HeadView的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

可添加头尾的RecycleView的实现

界面编码设计实现中,我们肯定会用到列表展示控件,大家肯定用过ListView。但是RecycleView大家发现有一个问题,我们如果想要为这个RecycleView添加自定义的头部view、尾部view的话,官方这个明显做不到,那这时我们可以考虑用装饰者模式或者继承去扩展一下。

itbird的专栏 447

带隙基准电路设计实战:从HSPICE仿真到Virtuoso版图全流程解析

在模拟集成电路设计中,基准电压源是确保系统精度与稳定性的核心模块。其基本原理在于巧妙结合具有正、负温度系数的电压,通过加权求和实现近似零温度系数的稳定输出,这一特性对于高精度数据转换器、电源管理芯片等至关重要。从工程实践角度,利用HSPICE进行深入的直流工作点、温度扫描和工艺角仿真,是验证电路性能、优化温度系数和电源抑制比的关键步骤。而借助Cadence Virtuoso进行版图实现时,必须重点关注电阻与BJT的匹配布局、敏感节点的保护以及电源完整性设计,以确保设计意图在硅片上得以准确呈现。通过完整的从前

weixin_29181861的博客 287

Android为RecyclerView设置header和footer(RecyclerView.Adapter和BaseQuickAdapter两种方式)

RecyclerView.Adapter的方式 private fun initView() { val list = arrayListOf<String>() repeat(9) { list.add(it.toString()) } binding.rvList.adapter = MyAdapter(list) binding.rvList.layoutManager = L.

张雨的博客 2490

SIwave仿真手册——信号完整性仿真之S参数的提取(二)

上一篇简单了讲述了软件的各个操作界面,本次博客更新关于的仿真,因为第二章完整的内容比较多,所以分成好几篇博客进行分享。

luohuo9844的博客 1万+

ENVI+SARscape实战:从哨兵一号数据到地震形变制图全流程解析

本文详细解析了使用ENVI和SARscape软件从哨兵一号数据生成地震形变图的全流程,包括数据获取、干涉处理、相位解缠等关键步骤。通过实战技巧和参数设置建议,帮助用户高效处理SAR数据,提升地震形变监测的精度和可视化效果。

weixin_30460489的博客 385

Android 原生Adapter添加底部局和头布局

主要注意下着三个方法 getItemViewType ,getItemCount,onCreateViewHolder (getItemCount size+1是加的底部或者头布局) @Override public int getItemViewType(int position) { ////通过position来控制在底部还是顶部 if (position == resu...

xxb52306的博客 688

逆向实战:手把手教你用Frida绕过Flutter App的SSL Pinning(附脚本修改指南)

本文详细介绍了如何利用Frida工具绕过Flutter应用的SSL Pinning保护机制,包括静态分析定位关键函数、定制Frida Hook脚本以及流量捕获的完整解决方案。通过实战案例和脚本修改指南,帮助安全研究人员有效应对Flutter应用的安全挑战,特别适用于安卓平台的逆向工程和抓包需求。

weixin_28723171的博客 404

问题解决:listview多次调用addHeaderView和addFooterView

情景: 有两个分类,每个分类下的数据用listview显示,分类1需要显示头视图和尾视图,分类2不要显示头视图和尾视图 。两个分类可以来回切换。实现的步骤: 1. addHeaderView 、 addFooterView,默认显示分类1的数据,setAdapter绑定 2. 点击分类2时,先removeheaderview、removefooterview,然后setAdapter重新绑定数据3...

weixin_30559481的博客 248

UNet改进(23):如何用SLCAM模块提升UNet的分割性能

本文提出一种改进的UNet架构,通过引入轻量化注意力模块(SLCAM)增强医学图像分割性能。SLCAM整合了通道和空间双重注意力机制:通道注意力采用全局池化和共享MLP学习通道权重,空间注意力通过7×7卷积捕捉上下文信息。网络在传统UNet基础上,在每个下采样和上采样块后加入SLCAM模块,并保持跳跃连接结构。实验表明,该方法能自适应聚焦重要特征,在不显著增加计算负担的情况下提升分割精度,特别适用于医学图像等需精确边界的场景。未来可探索三维注意力、动态参数调整等改进方向。

2501_91516851的博客 438

Go基础:Go语言详细介绍,环境搭建,及第一个程序详解

Go语言是Google开发的开源编程语言,具有高效、简洁、并发性强等特点。文章从Go语言的诞生背景、核心特性及应用领域展开介绍,并详细说明了Windows、Linux和macOS下的环境搭建步骤,包括安装、环境变量配置及测试方法。最后通过“Hello, World!”程序解析Go语言基本语法,并演示了编译发布和跨平台编译功能。全文涵盖了Go语言从入门到实践的完整流程,适合初学者快速上手。

数据知道的博客 6800

万能的RecyclerViewAdapter,支持上拉加载、添加HeadView

最近的项目,使用RecyclerView比较多,导致需要写大量的Adapter和ViewHolder。不想偷懒的程序员不是好程序员。于是,查了一些资料,对RecyclerView的Adapter进行了一些封装。使用的时候减少了大量的工作。 先来点效果图 1.gif 2.gif 封装后的Adapter使用: class DragSwipeAdapter extends

努力,可能成功!放弃,注定失败! 1298

核心组件大换血:Backbone与Neck魔改篇:YOLO26结合StarNet结构:2026星状网络在YOLO生态的即插即用实战

本文将介绍如何将StarNet作为Backbone替换YOLO26原生架构,以提升边缘设备上的目标检测性能。文章首先分析了YOLO26在特定场景下的精度瓶颈,指出其通用Backbone设计存在不足。随后深入解析StarNet的核心创新——星操作(Star Operation),这一低维计算却能获得高维特征表达的数学魔术,以及其极简的StarBlock模块设计。通过对比YOLO26原生架构的三大创新与痛点,作者提出两种替换策略:完整替换Backbone或局部替换+Neck联调。文中提供了StarNet核心代码

ZDQ58818的博客 289

Android 简捷地为RecyclerView添加HeadView和FootView

之前自己尝试用ViewType的思路去实现为RecyclerView添加HeadView和FootView,总感觉自己写的代码太啰嗦了,向两位大神学习了一下他们的编码思路 RecyclerView添加Header的正确方式 Android 优雅的为RecyclerView添加HeaderView和FooterView 写了个简单了些的,分享给大家。 废话不多说,上图上代码。

WillLiaowh的博客 3569

基于Simulink的自适应反步法(Adaptive Backstepping)控制​

本文针对非线性系统控制中未知参数和强非线性耦合的挑战,提出基于Simulink的自适应反步法解决方案。通过融合参数在线估计与反步递归设计,该方法显著提升了永磁同步电机(PMSM)速度控制的鲁棒性,使跟踪误差从20%降至3%,参数估计收敛时间小于0.5秒。文章详细阐述了从算法推导到Simulink实现的完整流程,包括系统架构设计、核心算法推导(以PMSM为例)、模块化建模方法、参数优化策略以及工程部署建议。提供的自适应控制器MATLAB代码和关键参数表可直接应用于实际工程,为电机驱动、机械臂等非线性系统控制提

xiaoheshang_123的博客 101

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Android RecyclerView添加头部与尾部

RecyclerView一个艺术般的控件,完全取代了之前的ListView与GridView,并且有着比ListView与GridView更加强大的功能,可是RecyclerView缺有个非诚明显的瑕疵,竟然没有封装addHeaderView和addFooterView方法,没办法只好自己想办法实现了:核心代码:private class RecyclerAdapter extends Recycl

奔跑的豆子的专栏 9082

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

android 头部布局返回,Recyclerview添加头布局和尾布局、item点击事件详解

简介:本篇博客主要包括recyclerview添加多种布局以及添加头布局和尾布局,还有item点击事件思路:主要重写Recyclerview.Adapter中的一些方法1.public int getItemCount() item熟练 +2(头布局和尾布局)2.public int getItemViewType(int position) 判断position 设置itemType3....

weixin_39568653的博客 505

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

RecyclerView添加头部 尾部view

【代码】RecyclerView添加头部 尾部view。

魑魅魍魉9527 1212

自定义Adapter给RecyclerView添加头和尾

一个超级简单的adapter添加头和尾的方法。 封装一个baseAdapter 固定

张小白的博客 1038

通用的RecyclerView Adapter适配器

在Android开发中,会经常用到RecyclerView来显示数据,数据的绑定使用到Adapter,原声的Adapter需要些很多重复代码,今天写了一个通用的代码来实现适配器绑定数据,减少代码量。 通用Adapter的功能: 1、FooterView和headerView的显示 2、停止滚动屏幕,再去加载数据 下面是代码的详解: 1、通用的ViewHolderpublic class R

u011521890的专栏 9435

RecyclerView超级万能适配器(多布局、head、foot、下拉刷新、上拉自动更多、滑动删除)

使用方法 GitHub APK下载 将libray模块复制到项目中,或者直接在build.gradle中依赖: allprojects { repositories { maven { url 'https://jitpack.io' } } } dependencies { compile '...

奋斗的IT青年 1376

学会自己给RecyclerView添加Header、Footer和加载更多回调

  我的视频课程:《FFmpeg打造Android万能音频播放器》 我的视频课程(编码直播推流):《Android视频编码和直播推流》           说来也惭愧,RecyclerView都出来了多么久了,但我还在listview中畅游,继续这样是不行的,是时候展现新的技术了。对于习惯了listview的我来说,刚开始觉得RecyclerView不就和listview一样吗,而且还没有...

ywl5320的专栏 1940

Recyclerview添加头布局和尾布局,点击效果

简介:   本篇博客主要包括recyclerview添加多种布局以及添加头布局和尾布局,还有item点击事件 思路:   主要重写Recyclerview.Adapter中的一些方法   1.public int getItemCount() item熟练 +2(头布局和尾布局)   2.public int getItemViewType(int position) 判断pos...

weixin_34396902的博客 190

RecycleView添加头布局尾布局

所有得逻辑操作都在adapter中 package com.example.myapplication; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.vie...

mintent的博客 402

多类型的RecyclerView

1.由于recyclerView没有提供像Listview一样的addheadView的方法,就需要我们自己设置head。 布局很简单上下两个头和脚布局。内容写了一些假数据。贴一下adapter中的代码:public class HeadFootAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { /**

ljngya的博客 555

Android LRecyclerView实现下拉刷新,滑动到底部自动加载更多

随着功能的不断优化,框架中的类或者接口名字会有变动,为了获取准确的使用方法,请参考最新的说明文档:点此查看。简介LRecyclerView是支持addHeaderView、 addFooterView、下拉刷新、分页加载数据的RecyclerView。它对 RecyclerView 控件进行了拓展,给RecyclerView增加HeaderView、FooterView,并且不需要对你的Adapte

Dream It Possible 10万+
上一篇: [Android]RecyclerViewAdapter的封装
下一篇: [Android]Maven 仓库的使用与私有仓库搭建
runstoppable
博客等级 码龄10年 1粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值