ListView的Item的滑动删除

仿QQ消息列表item横向滑动删除ListView中item侧滑删除 在最近的项目中,我的ListView中item选项是长按删除的效果(Android的通常做法长按或点击),老板觉得这个效果不好,提出要求做类似QQ消息列表横向滑动时删除消息的效果。 本博文实现思路是在滑动item的过程中修改item的leftMargin实现的。 阅读详情

第一次写自定义控件,虽然耦合度有点高,但是还是记录一下。

先来看一下效果
listview的Item滑动删除

第一步我打算把两个选项挤到屏幕外面,这样向左滑动的时候可以出现图中的效果。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/img"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:padding="5dp" />

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center_vertical"
        android:paddingLeft="10dp"
        android:text="content"
        android:textColor="#000000"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/open"
        android:layout_width="90dp"
        android:layout_height="match_parent"
        android:background="#c9c9ce"
        android:gravity="center"
        android:text="Open"
        android:textColor="#ffffff"
        android:textSize="18sp" />

    <ImageView
        android:id="@+id/delete"
        android:layout_width="90dp"
        android:layout_height="match_parent"
        android:background="#f93f25"
        android:scaleType="center"
        android:src="@drawable/ic_delete"
        android:textColor="#ffffff" />

</LinearLayout>

然后先是准备测试用的数据和适配器

public class MainActivity extends Activity implements OnItemClickListener {

    private AppAdapter mAdapter;
    private List<ApplicationInfo> mAppList;
    private SlideListView lv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mAppList = getPackageManager().getInstalledApplications(0);
        lv=(SlideListView) findViewById(R.id.listView);
        mAdapter=new AppAdapter(mAppList,this,lv);
        lv.setAdapter(mAdapter);
        lv.setList(mAppList);
        lv.setOnItemClickListener(this);

    }


    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // TODO Auto-generated method stub
        Log.i("ShunXu","onItemClick");
    }
}

AppAdapter.java:

public class AppAdapter extends BaseAdapter {
    private List<ApplicationInfo> mAppList;
    private Context context;
    private SlideListView lv;
    /**
     * @param mAppList
     * @param context
     */
    public AppAdapter(List<ApplicationInfo> mAppList, Context context,SlideListView lv) {
        super();
        this.mAppList = mAppList;
        this.context = context;
        this.lv=lv;
    }

    @Override
    public int getCount() {
        return mAppList.size();
    }

    @Override
    public ApplicationInfo getItem(int position) {
        return mAppList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.list_item, null);
            new ViewHolder(convertView);
        }
        final ViewHolder holder = (ViewHolder) convertView.getTag();
        ApplicationInfo item = getItem(position);
        holder.iv_icon.setImageDrawable(item.loadIcon(context.getPackageManager()));
        holder.open.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                lv.clearScroll();
            }
        });
        holder.tv_name.setText(item.loadLabel(context.getPackageManager()));
        holder.delete.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                lv.removeAndClearScroll();
            }
        });
        return convertView;
    }
    class ViewHolder {
        ImageView iv_icon,delete;
        TextView tv_name,open;
        public ViewHolder(View view) {
            iv_icon = (ImageView) view.findViewById(R.id.img);
            tv_name = (TextView) view.findViewById(R.id.tv);
            delete=(ImageView) view.findViewById(R.id.delete);
            open=(TextView) view.findViewById(R.id.open);
            view.setTag(this);
        }
    }
}

SlideLiseView.java

public class SlideListView extends ListView {

    /**
     * 滑动类
     */
    private Scroller scroller;
    /**
     * 当前项
     */
    private int currentPos;

    /**
     * 手指按下的位置
     */
    private int xDown;
    /**
     * 手指按下的位置
     */
    private int yDown;

    /**
     * listview的item
     */
    private View item;
    /**
     * 是否是滑开状态
     */
    private boolean isOpen = false;

    /**
     * 滑动临界值
     */
    private int minWidth;

    /**
     * listview中的list
     */
    private List<ApplicationInfo> list;

    /**
     * listview的适配器
     */
    private AppAdapter adapter;

    public SlideListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        scroller = new Scroller(context);
        minWidth = dip2px(context, 90);
    }

    public List<ApplicationInfo> getList() {
        return list;
    }

    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    public void setList(List<ApplicationInfo> list) {
        this.list = list;
    }

    public AppAdapter getAdapter() {
        return adapter;
    }

    @Override
    public void setAdapter(ListAdapter adapter) {
        // TODO Auto-generated method stub
        super.setAdapter(adapter);
        this.adapter = (AppAdapter) adapter;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.i("ShunXu", "dispatchTouchEvent");

        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.i("ShunXu", "dispatchTouchEvent" + "----ACTION_DOWN");
            // 初始化点击位置
            xDown = (int) ev.getX();
            yDown = (int) ev.getY();
            break;

        case MotionEvent.ACTION_MOVE:
            Log.i("ShunXu", "dispatchTouchEvent" + "----ACTION_MOVE");
            break;
        case MotionEvent.ACTION_UP:
            Log.i("ShunXu", "dispatchTouchEvent" + "----ACTION_UP");
            break;
        }

        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        Log.i("ShunXu", "onInterceptTouchEvent");
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.i("ShunXu", "onInterceptTouchEvent" + "----ACTION_DOWN");
            int pos = pointToPosition(xDown, yDown);
            // 如果item为null的话,肯定是第一次进来还没有点击
            if (item == null) {
                isOpen = false;
            }
            // 滑开状态之后的点击有两种情况,一种是又点击自身,一种是点击别的item了
            if (isOpen) {
                if (pos != currentPos) {
                    MotionEvent cancelEvent = MotionEvent.obtain(ev);
                    cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
                    clearScroll();
                    currentPos = pos;
                    // 点击别的item就把原来的item复位,复位之后取消本次ontouch事件,不让它向下传递
                    onTouchEvent(cancelEvent);
                    return false;
                } else {
                    return false;
                }

            }
            // 通过点击位置拿到item在list中的位置
            currentPos = pointToPosition(xDown, yDown);
            if (currentPos == AdapterView.INVALID_POSITION) {
                return false;
            }
            // 注意这里要减去getFirstVisiblePosition(),因为getChildAt函数拿到的
            // position的范围是当前屏幕可见item个数,所以如果直接写item在list中的绝对位置
            // 会导致后面的item拿不到,
            item = getChildAt(currentPos - getFirstVisiblePosition());
            break;
        case MotionEvent.ACTION_MOVE:
            Log.i("ShunXu", "onInterceptTouchEvent" + "----ACTION_MOVE");
            break;
        case MotionEvent.ACTION_UP:
            Log.i("ShunXu", "onInterceptTouchEvent" + "----ACTION_UP");
            break;

        }
        return false;

    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        Log.i("ShunXu", "onTouchEvent");
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.i("ShunXu", "onTouchEvent" + "----ACTION_DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            Log.i("ShunXu", "onTouchEvent" + "----ACTION_MOVE");
            int dx = (int) (xDown - ev.getX());
            if (dx <= minWidth * 2) {
                // 手指向左滑
                if (dx > 0) {
                    if (item != null) {
                        item.scrollTo(dx, 0);
                    }
                } else if(isOpen){
                    item.scrollTo(start+dx, 0);
                }
            }

            break;

        case MotionEvent.ACTION_UP:
            Log.i("ShunXu", "onTouchEvent" + "----ACTION_UP");
            int distance = (int) (xDown - ev.getX());
            if (distance > 50) {
                if (distance >= minWidth) {
                    scroller.startScroll(item.getScrollX(), 0, minWidth * 2 - item.getScrollX(), 0, 300);
                    postInvalidate();
                    isOpen = true;
                } else if (distance < minWidth) {
                    clearScroll();
                }
            }else if(distance<0&&isOpen){
                //如果手指向右滑动距离小于一个选项的宽度,就让他回复open状态
                if (distance > -minWidth) {
                    //从当前位置退回滑动距离即复原open状态
                    //View.getScrollX()return的mScrollX,始终是View的内容与View左边缘的距离
                    //所以当我们向右滑动的时候,其实是把mScrollX变小了,所以这里要用-distance把mScrollX变大
                    //之前忘了这一点,通过试参数试出来效果,然后又去看了下书才想起来getScrollX()的含义
                    scroller.startScroll(item.getScrollX(), 0, -distance, 0, 300);
                }
                //如果滑动距离大于一个选项宽度,就把选项关闭
                else if (distance < -minWidth) {
                    clearScroll();
                }
            }


            break;
        }

        return super.onTouchEvent(ev);
    }

    int start;

    /**
     * 配合Scroller实现View的平滑滚动
     */
    @Override
    public void computeScroll() {
        if (scroller.computeScrollOffset()) {
            if (item != null) {
                item.scrollTo(scroller.getCurrX(), scroller.getCurrY());
                postInvalidate();
                start = item.getScrollX();

            }
        }

    }

    /**
     * 选项回归原位
     */
    public void clearScroll() {
        if (item != null) {
            scroller.startScroll(item.getScrollX(), 0, -item.getScrollX(), 0, 300);
        }
        postInvalidate();
        isOpen = false;
    }

    /**
     * 点击删除按钮,执行删除动画及list的删除/adapter的更新
     */
    public void removeAndClearScroll() {

        if (item != null) {
            clearScroll();
            final int height = item.getMeasuredHeight();
            Animation animation = new Animation() {
                @Override
                protected void applyTransformation(float interpolatedTime, Transformation t) {
                    ViewGroup.LayoutParams layoutParams = item.getLayoutParams();
                    layoutParams.height = height - (int) (height * interpolatedTime);
                    item.setLayoutParams(layoutParams);
                }
            };
            animation.setDuration(300);
            animation.setAnimationListener(listener);
            startAnimation(animation);
        }
    }

    AnimationListener listener = new AnimationListener() {

        @Override
        public void onAnimationStart(Animation animation) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onAnimationRepeat(Animation animation) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            // TODO Auto-generated method stub
            list.remove(currentPos);
            adapter.notifyDataSetChanged();
            isOpen = false;
        }
    };



}

参考
https://github.com/yydcdut/SlideAndDragListView
app下载地址
https://github.com/yydcdut/SlideAndDragListView/blob/master/apk/sdlv.apk?raw=true

本来是想看人家大神的代码的,但是看了半天看不懂O.O,只好自己写了一个,这是我的第一个自定义控件,之前一直觉得自定义控件好难,现在总算是迈出了第一步了。加油!

Android滑动删除listview的Item 要点:自定义ListView,overwrite方法 dispatchTouchEvent 和 onTouchEvent;使用Scroller工具类; @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTIO... 阅读详情

相关推荐

Android 自定义ListView实现Item左右滑动删除

最近工作之中,要实现ListView左右滑动删除Item功能,在此做个记录。 案例图: 1.自定义ListView import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.ViewConfigurati

安卓兼职framework和app工程师的博客 864

flutter 中使用flutter_slidable 实现左滑显示删除、修改菜单,仿微信

【代码】flutter 中使用flutter_slidable 实现左滑显示删除、修改菜单,仿微信。

初遇你时动了情 4416

实现Android ListView滑动删除Item的完整指南

ListView作为Android开发中常用的组件之一,其背后的工作原理相对简单。在内部,ListView通过一个Adapter作为中介,将数据源和视图联系起来。当ListView需要显示数据时,它会请求Adapter获取行视图(row views),然后将数据填充到这些视图中,最后将它们渲染到屏幕上。这个过程是动态的,随着用户滚动屏幕,ListView会重复请求和渲染的过程。自定义ViewGroup类是扩展ViewGroup的子类,它允许开发者自定义布局的创建和子视图的绘制过程。

weixin_42103128的博客 880

Flutter从ListView的左滑删除,简单理解Key、Widget与Element之间的关系

关于Flutter学习的相关Demo源码,已经上传至Github. 有兴趣的同学,欢迎Star或Flow。我会不及时更新上传相关知识点源码 https://github.com/SunnyLy/flutter_sunny_demo 一、原由 最近在学习Flutter中ListView组件的使用。一看到ListView很自然的就会想到以下操作点: 下拉刷新; 上拉加载更多; 添加头部、底部等; Item滑动(左滑删除) 在做的过程中,我就先仿微信,选择实现左滑删除。想实现的效果如下: ListVi.

死磕到底 3922

ListView的item水平滑动(类QQ的左滑显示删除按钮)

QQ的一个聊天界面的listview每一行向左滑动的时候,会出现删除的按钮,特别炫酷,这个效果可以有,今天跟大家分享下。

自定义listView实现滑动显示删除按钮

自定义listView实现滑动显示删除按钮,

Flutter-listview的item左右滑动,删除item

import 'package:flutter/material.dart'; //列表左右滑动删除 void main() => runApp(MaterialApp( home: HomePage(), )); class HomePage extends StatelessWidget { final List<String> ite...

IT技术专栏 2413

Flutter中ListView侧滑菜单

Flutter中ListView侧滑菜单 项目地址:https://github.com/letsar/flutter_slidable 如何使用: 在pubspec.yamlflutter项目的中,添加以下依赖项: flutter_slidable:“ ^ 0.5.4 ” 在页面中引用 import 'package:flutter_slidable/flutter_slidable.dart'; 具体使用 Slidable( actionPane: SlidableDrawerActionPane(), //滑动风格 actionExtentRatio: 0.25, ch

如何实现滑动删除功能

我们在这里介绍的Dismissible是一个事件响应Widget,它和GestureDetector类似,不过它只能响应滑动事件,它经常配合ListView使用,用来删除List中的某一个项目,我们在本章回中将详细介绍它的使用方法。

talk_8的专栏 1029

OpenSSL玩转证书链:从Windows CA根证书到签发多域名/IP的服务器证书全攻略

本文详细介绍了如何使用OpenSSL在Windows环境下构建私有CA体系,从创建CA根证书到签发支持多域名/IP的服务器证书的全流程。通过实战指南,读者可以掌握零成本证书管理技术,灵活配置SAN扩展,并了解在Nginx、Apache等主流服务器中的证书部署方法,适用于企业内网、IoT设备等HTTPS加密场景。

weixin_28731223的博客 440

告别手动标注!用ENVI Classic高效搞定高光谱图像语义分割标签(以农业/地物分类为例)

本文详细介绍了如何利用ENVI Classic实现高光谱图像的半自动化智能标注,特别针对农业和地物分类场景。通过光谱特征分析、智能标注技巧和MAT文件转换,显著提升标注效率和质量,助力AI模型训练。

weixin_28694169的博客 251

Flutter开发-------侧滑删除

侧滑删除前言主要技术实现效果实例代码分析叠层的使用状态管理的使用控制按钮的布局和动画列表布局代码 前言 昨天的一个需求,需要完成侧滑删除这个功能,现在Dismissible的功能需求满足不了现在的项目需求,就自己封装一个小组将 主要技术 涉及到叠层,动画,状态管理 实现效果 实例代码分析 叠层的使用 child: Stack( children...

追逐蓦然 3302

保姆级教程:在mmdetection中手动计算并可视化P、R、F1值(附完整代码)

本文提供了一份详细的mmdetection教程,指导开发者如何手动计算并可视化精确率(P)、召回率(R)和F1值。通过完整的代码示例和清晰的步骤说明,帮助用户深入理解目标检测模型的性能评估方法,特别适合需要精细分析模型表现的计算机视觉研究人员和工程师。

weixin_29038303的博客 399

listview滑动删除item的一个方案

功能:在listview上,向右滑动,直接删除一个item 主要实现思路: 检测listview的touch操作,down时,记录位置,up时,做删除。 部分代码: mListView.setOnTouchListener(new OnTouchListener() { private int mDownX = 0; private int mDownY = 0

胡老哈的学习记录 2015

深度学习的unfold操作

对于彩色图像这样的三维数据,unfold操作会对每个通道分别进行上述的二维展开操作。例如,一个 RGB 图像,在对其进行unfold操作时,红色通道、绿色通道和蓝色通道的数据都会被独立地按照定义的窗口和步长展开,然后将这些展开后的通道数据按照原来的通道顺序组合在一起,形成新的张量。与我们熟悉的卷积类似,unfold也是使用一个特定大小的窗口和步长自左至右、自上至下滑动,不同的是,卷是滑动后与核求乘积(所以取名为卷积),而unfold滑动后不求乘积,是将窗口内的数据展开。

xulibo5828的博客 2164

SpringBoot 通过 JMS 集成 IBM MQ

IBM MQ 作为老牌的企业级消息中间件,虽然在当下云原生时代已不再是主流选择,但在金融、银行、保险等传统行业的核心业务系统中仍然占据着重要地位。这些行业对系统的稳定性、可靠性和事务一致性有着极高的要求,IBM MQ 正是在这些方面表现出色。尽管近年来 RabbitMQ、Apache Kafka 等新一代消息中间件在新兴项目中更受欢迎,但许多金融公司和大型企业仍在使用 IBM MQ 作为核心业务系统的消息传递基础设施。

小单的博客专栏 949

Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果

我在上一篇文章中Android 带你从源码的角度解析Scroller的滚动实现原理从源码的角度介绍了Scroller的滚动实现原理,相信大家对Scroller的使用有一定的了解,这篇文章就给大家带来使用Scroller的小例子,来帮助大家更加熟悉的掌握Scroller的使用,掌握好了Scroller的使用我们就能实现很多滑动的效果。例如侧滑菜单,launcher,ListView的下拉刷新等等效果,我今天实现的是ListView的item的左右滑动删除item的效果,现在很多朋友看到这个效果应该是在Andr

Mobile Internet developer 13万+

Vivado ILA调试全攻略:从HDL实例化到Block Design的5个实战技巧

本文全面解析了Vivado集成逻辑分析仪(ILA)的五种核心调试方法,涵盖从HDL代码实例化到Block Design集成的实战技巧。详细对比了不同方法的优缺点与适用场景,并重点介绍了如何利用Debug Hub高效管理多时钟域复杂调试,旨在帮助FPGA开发者精准定位问题,显著提升板级调试效率。

weixin_29214199的博客 376

滑动删除ListView的Item

转载请注明出处:  在玩QQ的时候,我们会看到这样的效果,可以滑动删除消息,下面就模拟一下这样的效果。 1.创建一个类ListViewCompat,继承ListView。   重写其OnTouchEvent事件。 @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAc

forwardyzk的专栏 1535

C#计算八字

private string[] jq = { "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至" };private string[] dz = { "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥", "子" };

m0_72939038的博客 827

SHAP图全解析:从理论到实践,教你如何读懂和优化模型特征

本文全面解析SHAP图,从博弈论基础到实战应用,指导读者如何解读和利用SHAP值优化机器学习模型。通过详解特征重要性条形图、小提琴图、依赖图及决策图等关键可视化工具,帮助数据科学家精准诊断模型、识别特征交互,并将洞见转化为特征工程与模型调试的实际行动,有效提升模型可解释性与性能。

svm4gardener的博客 188

关于listview的item实现滑动删除功能实现

最近做了一个仿苹果风格的图片浏览器,用到的技术是listview的item滑动删除功能 有兴趣的朋友可以去网上下载一个看看实际效果,可以和我交流交流 下载链接: http://www.mumayi.com/android-320402.html

sunxingzhesunjinbiao的专栏 1082

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

listView的item向左滑动实现删除

有一种删除功能是这样的: ListView的item向左滑动,实现删除功能 注释很清楚,简单明了 1.自定义LeftDeleteView.java继承HorizontalScrollView.java public class LeftDeleteView extends HorizontalScrollView { private int start;//开始滑动的

u012123938的专栏 4511

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

左右滑动删除ListView条目Item(SwipeToDismiss)

Android的SwipeToDismiss是github上一个第三方开源框架(github上的项目链接地址:https://github.com/romannurik/Android-SwipeToDismiss )。该开源项目旨在:使得一个ListView的item在用户的手指在屏幕上左滑或者右滑时候,删除当前的这个ListView Item。 package com.example

Rokends的博客 648

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Android 用HorizontalScrollView实现ListView的Item滑动删除

Android 用HorizontalScrollView实现ListView的Item滑动删除  作者:Mark Yong,   发表于:2014-8-5,   浏览量:503,   更新于:2014-8-5 用HorizontalScrollView实现类似微信的滑动删除 测试于:Android2.2+ 对于Android来说按键操作已经在减少,越来越多的手势操作层出不

编程之美 2938

模仿android4.0的 通知栏 listview 滑动删除 item ,有滑动动画。

在QQ群里,很多朋友问如何实现android4.0的通知栏里面的listview滑动删除一个item的效果,我这里简单实现了一下,看图吧(一图胜千言)。 效果图片 实现思路 思路:1、给listview添加一个滑动监听事件(在该事件中获得滑动的位置,从而获得listview的item)。              2、让这个item播放一个动画(从左滑动到右)

michael Yang的专栏 5395
上一篇: 反编译
下一篇: View的事件分发机制
普通网友
博客等级 码龄12年 7粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值