如何应对Android面试官->嵌套滚动原理大揭秘,实战京东首页二级联动

Android 嵌套滑动总结,真牛 要用实现嵌套滑动非常简单,只要按如下编写布局文件:// 可滑动部分 阅读详情

前言

本章节主要从 嵌套滑动、滑动冲突方案解决来入手,这里不是基于协调者布局;

嵌套滑动

我们先来看一下淘宝和京东的首页滑动效果:

可以看到首页是有一个嵌套滑动的效果,上推的时候,频道先跟着移动,然后置顶不动,这种效果基于协调者布局可以实现,但是如果没有协调者布局的情况下,如何实现呢?

界面如何布局

在不使用 协调者 布局的情况下,界面最终的布局效果应该是类似下面这样的一层结构;

最外层 ScrollVIew/NestedScrollView

嵌套:不能滑动的RecyclerView、TabLayout、ViewPager

经过分析,我们来搭建一个这样的布局来看下

<ScrollView    
    android:layout_width="match_parent"    
    android:layout_height="match_parent"    
    android:orientation="vertical">  
      
    <LinearLayout        
        android:layout_width="match_parent"        
        android:layout_height="match_parent"        
        android:orientation="vertical">
        <!-- 这里要稍微改造下,改成不能滑动的 RecyclerView -->     
        <androidx.recyclerview.widget.RecyclerView            
            android:id="@+id/combo_top_view"            
            android:layout_width="match_parent"            
            android:layout_height="wrap_content" />        
        <LinearLayout            
            android:layout_width="match_parent"            
            android:layout_height="match_parent"            
            android:orientation="vertical">            
            <com.google.android.material.tabs.TabLayout                
                android:id="@+id/tablayout"                
                android:layout_width="match_parent"                
                android:layout_height="wrap_content" />            
            <androidx.viewpager2.widget.ViewPager2                
                android:id="@+id/viewpager_view"                
                android:layout_width="match_parent"                
                android:layout_height="match_parent" />        
        </LinearLayout>    
    </LinearLayout>
</ScrollView>

然后我们编译执行下,看下最终的滑动效果,是否能达到我们的预期:

可以看到,并没有达到我们期望的联动效果,那么原因是什么呢?

View 和 ViewGroup 的关系

  1. 代码层面:ViewGroup 继承 View;
  2.  运行层面:ViewGroup 嵌套 View;

事件分发是从运行时角度来分析的;

事件分发的流程

Activity dispatchTouchEvent -> 

public boolean dispatchTouchEvent(MotionEvent ev) {    
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {        
        onUserInteraction();    
    }    
    if (getWindow().superDispatchTouchEvent(ev)) {        
        return true;    
    }    
    return onTouchEvent(ev);
}

PhoneWindow superDispatchTouchEvent ->

public boolean superDispatchTouchEvent(MotionEvent event) {
    return mDecor.superDispatchTouchEvent(event);
}

DecorView superDispatchTouchEvent -> 

public boolean superDispatchTouchEvent(MotionEvent event) {
    return super.dispatchTouchEvent(event);
}

DecorView 的父类是 FrameLayout,其父类是 ViewGroup,最终调度到 ViewGroup 的 dispatchTouchEvent 方法

这 dispatchTouchEvent 方法中,先进行是否需要拦截判断,通过 onInterceptTouchEvent 方法

public boolean dispatchTouchEvent(MotionEvent ev) {
    //
    ...
    // 省略部分代码
    // 首先问询自身要不要进行事件的拦截
    final boolean intercepted;
    if (actionMasked == MotionEvent.ACTION_DOWN        
            || mFirstTouchTarget != null) {    
        final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;    
        if (!disallowIntercept) {        
            intercepted = onInterceptTouchEvent(ev);        
            ev.setAction(action); // restore action in case it was changed    
        } else {        
            intercepted = false;    
        }
    } else {    
        // There are no touch targets and this action is not an initial down    
        // so this view group continues to intercept touches.    
        intercepted = true;
    }
}
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;

这个是用来判断子 View 有没请求父 View(当前View)不要进行事件的拦截

子 View 通过调用这个方法,设置 mGroupFlags 的值,来修改 disallowIntercept 的逻辑;

如果子 View 没有要求父 View 不拦截,则父View(当前View)执行 onInterceptTouchEvent 来问询自身要不要拦截;

如果自身不拦截,则

嵌套滚动的实现原理

需要两个角色,一个角色用来实现 NestedScrollingParent3,一个角色需要实现 NestedScrollingChild3 接口,用来表示一个是父亲,一个是孩子,以此来表示它们之间的嵌套滑动;

那么,有人就提出了,使用 NestedScrollView,因为它实现了 NestedScrollingParent3,那么我们将布局改成 NestedScrollView :

<androidx.core.widget.NestedScrollView    
    android:layout_width="match_parent"    
    android:layout_height="match_parent"    
    android:orientation="vertical">  
      
    <LinearLayout        
        android:layout_width="match_parent"        
        android:layout_height="match_parent"        
        android:orientation="vertical">
        <!-- 这里要稍微改造下,改成不能滑动的 RecyclerView -->     
        <androidx.recyclerview.widget.RecyclerView            
            android:id="@+id/combo_top_view"            
            android:layout_width="match_parent"            
            android:layout_height="wrap_content" />        
        <LinearLayout            
            android:layout_width="match_parent"            
            android:layout_height="match_parent"            
            android:orientation="vertical">            
            <com.google.android.material.tabs.TabLayout                
                android:id="@+id/tablayout"                
                android:layout_width="match_parent"                
                android:layout_height="wrap_content" />            
            <androidx.viewpager2.widget.ViewPager2                
                android:id="@+id/viewpager_view"                
                android:layout_width="match_parent"                
                android:layout_height="match_parent" />        
        </LinearLayout>    
    </LinearLayout>
</androidx.core.widget.NestedScrollView>

我们运行看下效果:

虽然实现了嵌套滚动,但是 TabLayout 没有吸顶,随着滑动一起滚出了屏幕,还是不符合预期;

那么如何实现吸顶来达到我们的预期呢?

我们可以将 NestedScrollView  的内容元素进行拆分,将不能滑动的区域作为 NestedScrollView  的 header 部分,将 TabLayout 和 RecyclerView 整体划分成一部分作为 NestedScrollView 的最后一个 View,并且最后一个 View 的高度是整个屏幕的高度,这样当 NestedScrollView 滑动到最后一个 View 的时候,整个View 是充满屏幕的,那么 TabLayout 就能置顶了;

那么我们就需要这个 NestedScrollView 来判断最后是不是一个 View,以及获取最后一个View之后,设置它的高度为屏幕高度;

继承 NestedScrollView 实现下面两个方法:

@Override
protected void onFinishInflate() {    
    super.onFinishInflate();    
    // 根据 xml 的层级结构,我们需要获取的是第一个子 View 下的 第二个子 View    
    contentView = ((ViewGroup) getChildAt(0)).getChildAt(1);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);    
    // 重新设置 contentView 的高度为屏幕高度    
    ViewGroup.LayoutParams layoutParams = contentView.getLayoutParams();    
    layoutParams.height = getMeasuredHeight();    
    contentView.setLayoutParams(layoutParams);
}

我们编译运行看下:

可以看到,达到了我们期望的效果,实现了吸顶,但是还是有滑动冲突的地方,没有达到预期的效果,触摸滑动的时候 NestedScrollView 没有先滑动,而是 RecyclerView 滑动了一些距离才进行 NestedScrollView 的滑动;

我们可以根据嵌套滑动流程图来分析下:

根据流程图,可以知道,调用 startNestedScrolled 的时候,说明开始滑动了,我们进入 RecyclerView 的 startNestedScroll 方法看一下:

@Override
public boolean startNestedScroll(int axes) {    
    return getScrollingChildHelper().startNestedScroll(axes);
}

这里通过一个 Helper 帮助类,来处理滑动事件,我们进入这个 Helper 看下

public boolean startNestedScroll(@ScrollAxis int axes) {    
    return startNestedScroll(axes, TYPE_TOUCH);
}
public boolean startNestedScroll(@ScrollAxis int axes, @NestedScrollType int type) {    
    if (hasNestedScrollingParent(type)) {        
        // Already in progress        
        return true;    
    }
    // 判断有没有开启嵌套滑动    
    if (isNestedScrollingEnabled()) {
        // 获取当前 View 的 parent        
        ViewParent p = mView.getParent();        
        View child = mView;        
        while (p != null) {
            // 问询这个 parent 是否支持嵌套滑动            
            if (ViewParentCompat.onStartNestedScroll(p, child, mView, axes, type)) {                
                setNestedScrollingParentForType(type, p);
                // 如果支持,接受嵌套滑动                
                ViewParentCompat.onNestedScrollAccepted(p, child, mView, axes, type);                
                return true;            
            }            
            if (p instanceof View) {                
                child = (View) p;            
            }            
            p = p.getParent();        
        }    
    }    
    return false;
}

因为是 NestedScrollView 所以肯定支持嵌套滑动,这里遇到 NestedScrollView 的时候就会 return true;

当手指滑动的时候,正常应该是先让 NestedScrollView 滑动,等它不能滑动的时候,RecyclerView 才进行滑动;

开始滑动的时候,RecyclerView 会执行 dispatchNestedPreScroll,而 NestedScrollView 则会执行 onNestedPreScroll 方法,来判断并且决定 NestedScrollView 要不要执行滑动

@Override
public void onNestedPreScroll(@NonNull View target, int dx, int dy, @NonNull int[] consumed,        
        int type) {    
    dispatchNestedPreScroll(dx, dy, consumed, null, type);
}
@Override
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow,        
        int type) {    
    return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow, type);
}

我们发现在 NestedScrollView 中它又去问询它的父亲能不能滑动了,这里就和 RecyclerView 冲突了,这是因为 NestedScrollView 即可以当父亲也可以当孩子导致,那么上面的问题原因也就找到了,我们把 NestedScrollView 当成了父亲,那么它就不需要再去问询自己的父亲了,只需要判断下自己能不能滑动,能滑动就自己滑动,同时记录消费的距离;

所以我们复写 NestedScrollView 的 onNestPresScroll 方法,在 RecyclerView 滑动之前,自己先处理滑动;

public void onNestedPreScroll(@NonNull View target, int dx, int dy, @NonNull int[] consumed) {    
    // 我们需要处理不可滑动的区域的可见高度    
    boolean hideTop = dy > 0 && getScrollY() < topView.getMeasuredHeight();    
    if (hideTop) {        
        scrollBy(0, dy);        
        consumed[1] = dy;    
    }
}

编译后效果如下:

可以看到,已经可以吸顶,并且先滑动顶部,再滑动 RecyclerView;但是在快速滑动之后的惯性滑动还是没有;我们需要加上惯性滑动,来保证体验的完美;

我们需要接入 Fling 来实现,重写 fling 方法,让子View RecyclerView fling 同样的值;

public void fling(int velocityY) {    
    super.fling(velocityY);    
    if (velocityY > 0) {        
        ViewPager2 viewPager2 = getChildView(this, ViewPager2.class);        
        if(viewPager2 != null) {                      
            RecyclerView childRecyclerView = getChildView(((ViewGroup)viewPager2.getChildAt(0)), RecyclerView.class);            
            if (childRecyclerView != null) {                
                childRecyclerView.fling(0, velocityY);            
            }        
        }    
    }
}

我们运行看下效果:

可以看到,实现了惯性滑动的效果,perfect~~

简历润色

简历上可写:深度理解嵌套滑动实现原理,可实现复杂的嵌套滚动效果;

下一章预告

事件冲突与解决方案大揭秘;

欢迎三连

来都来了,点个关注点个赞吧,你的支持是我最大的动力~~~

Android实现淘宝、京东首页浏览效果 CoordinatorLayout+AppBarLayout+TabLayout+ViewPager+Fragment 实现淘宝、京东首页效果 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客: 全新的 阅读详情

相关推荐

H3C ACL的应用与配置1

SWHC1-acl-ipv4-adv-3000]rule 30 permit ip source 192.168.50.252 0 destination 192.168.70.252 0 //设置一条ID为30的过滤,允许源地址为 192.168.50.252 访问目的地址为192.168.70.252 的设备。高级ACL范围3000-3999:对源IP,目地IP,协议,端口号进行过滤。[SWHC1]acl number 3000 //创建高级ACL 3000。

weixin_41120428的博客 2425

Android 嵌套滑动

在 Android 的事件分发机制当中,对于同一个事件流,如果由父控件拦截/消费了,那么子控件就没办法再获取到该事件流,从而造成在嵌套滑动时的不连贯。 使用嵌套滑动机制可以有效的解决上面的问题。它并没有改变事件分发机制,在发生嵌套滑动时,还是先进行事件分发,由父控件将事件分发给子 View,由子 View 进行消费。只不过,子 View 在自己消费之前,会先去询问父控件,是否需要处理滑动事件。于是才有了“在嵌套滑动中,子 View 是主动的”这样的说法。 下面我们就结合源码看看嵌套滑动是如何实现的。 一、源

tmacfrank 1414

单细胞转录组聚类分析R包——SC3的应用

前言 在做单细胞相关聚类分析的过程中,为了研究异质性,发现了一种专门用于单细胞转录组的聚类分析R包——SC3(single cell consensus clustering,单细胞一致性聚类)。该聚类算法发表于Nature Methods(2017),能够让单细胞RNA-seq基于转录组特征对细胞类型进行定量表征。这是一种用户友好的无监督聚类工具,它通过一致方法将多个聚类解决方案组合在一起,从而得到高精度和鲁棒性的分群结果。SC3包的官方具体使用教程见:http://www.bioconductor.or

m0_51042606的博客 5004

Android嵌套滑动机制

我们先来看一下动图,直观的感受下什么是嵌套滚动?嵌套就说明是。上图中,当我们滑动下面红色的UI控件时,先滑动的却是其父容器,当父容器滑动到一定程度后,下面红色的UI控件才开始滑动。那么嵌套滑动机制比ViewGroup的事件分发机制有什么优越之处呢?假设我们按照传统的事件分发去理解,首先我们滑动的是下面的红色的UI控件,而移动却是其父容器,所以按照传统的方式,肯定是父容器拦截了内部的红色的UI控件的事件。但是,,因为当父容拦截之后,是没有办法再把事件交给红色的UI控件的。

walk的博客 792

GEE开发之ERA5(气温、降水、压力、风速等)数据获取和分析

前言:ERA5主要提供DAILY和MONTHLY两大类别数据,其中主要包括气温、降水、压力、风速等。

等待着冬天的风的博客 3万+

Hive数据迁移

【迁移背景】 本次需要将老集群的hive数据(共30多张表)迁移至新集群中。 老集群版本为CDH5.13,未启用kerberos; 新集群版本为CDH5.14,启用了kerberos。 由于cloudera官方文档说明,在5.x的版本不支持从未启用kerberos的集群与启用了kerberos的集群之间的数据复制。因此无法通过bdr方式进行数据同步。于是采用手工方式进行测试验证。 第一步...

wangkuangood3200的专栏 469

一篇文章搞定《Android嵌套滑动》

说起嵌套滑动,那不得不说起一些电商的首页。 多层的列表滑动、左右滑动列表、上下滑动列表、吸顶Table。充斥着嵌套滑动。 所以本文也会模拟电商的首页去讲解我们的嵌套滑动。 外部与内部滑动方向不一致、外部与内部滑动方向一致、多种情况下的嵌套(电商首页)/外部拦截法、内部拦截法、现有API框架、NestedScrolling机制、ViewPage和RecyclerView、ScrollView嵌套ScrollView

小孟来码的博客 9261

【异常】解决 Claude Code 及第三方插件提示 “API Error: 404“ 的配置修复指南

在使用 Claude 相关的 CLI 工具(如)或 IDE 插件进行开发辅助时,配置错误的模型参数是导致连接失败的常见原因。本文将针对这一典型报错进行复盘与解决。

奶爸的编程之路,也就一周冷个三天 7746

Android仿今日头条详情页---多子view嵌套滚动方案

一、背景 类似百度APP、今日头条等产品的新闻详情页的实现。ELinkageScrollLayout给出了一种多子view嵌套滑动的解决方案。下文我们统一叫做"联动容器" 项目地址:ELinkageScrollLayout 直观感受下联动容器嵌套滚动的Demo效果: 二、分析 同大多数自定义控件类似,联动容器也需要处理子view的测量、布局以及手势处理。测量和布局对联动容器的场景来说非常简单,手...

Lorien Zhang的博客 1850

液压轴位置闭环控制(比例伺服阀应用)

液压阀的基础知识请参看下面的博客文章:PLC液压控制系列之比例流量阀结构分析_RXXW_Dor的博客-优快云博客比例流量阀液压同步控制的PID闭环调节可以参看下面这篇博文三菱FX3U-PLC 前馈+PID闭环调节实现液压同步控制(比例换向阀)_RXXW_Dor的博客-优快云博客液压控制系统在工业现场应用非常广泛,这篇博文我们简单分析下液压同步控制。这套系统的液压缸为单液压缸,首先简单介绍下什么是单作用液压缸,液压系统的详细理论分析大家可以找些专业书籍学习。

RXXW_Dor的博客 2262

华为od 面试八股文_前端_01_含答案

华为od 面试八股文_前端_01_含答案

MISAYAONE的博客 2748

探秘NestedRecyclerView:优雅地解决Android嵌套滚动问题

探秘NestedRecyclerView:优雅地解决Android嵌套滚动问题 在Android开发中,我们常常需要处理各种复杂的布局,其中嵌套滚动是一个常见的需求,例如在一个列表项中包含另一个可滚动的视图。为了解决这个问题,Google引入了NestedScrollView。而现在,我想要向您推荐一个更加强大且灵活的解决方案——。这个开源项目提供了一个自定义的RecyclerView,支持嵌套滚...

gitblog_00080的博客 1039

ROS2入门到精通—— 2-9 ROS2实战:Nav2常见的工程问题(参考3D视觉工坊)

本文介绍了Nav2常见的工程问题,还有调试DWB的一些经验,以及DWB的一些缺点

BigDavid123的博客 1068

如何应对Android面试官-> NestedScrollView 嵌套滑动机制详解,手写 NestedScrollView 核心实现

NestedScrollView嵌套滑动机制详解,手写NestedScrollView核心实现,大厂面试官助你轻松应对嵌套滑动连环炮

IT_Android的博客 4487

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

大龄程序员的2024年1月总结:转岗、热榜、分享、健康、技术文章

一月总结

IT_Android的博客 1243

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

生活生下来活下去

最近一直在追的一部小说,确切的说是追的一位作者『黑色枷锁』,我从2015年开始就在看他的小说,第一部小说『我的老千生涯』(已完结),第二部小说『我的老千江湖』(已完结),第三部小说『新民间老八门前传』(已2完结),第四部小说『新民间老八门』(连载中),小说写的很有意思,写江湖,写微表情,写人情世故,作者将自己的一些亲身经历融合到了故事情节中,里面也有很多让我觉得有意思的语录,摘抄一些。后续如果产品上使用了 Compose 的技术,我也会告诉大家来体验一下;希望接下来的日子里,病毒远离我!

452

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Android Tab吸顶 嵌套滚动通用实现方案✅

很多应用的首页都会有一些嵌套滚动、Tab吸顶的布局,尤其是一些生鲜类应用,例如 朴朴超市、大润发优鲜、盒马等等。在 Android 里面,滚动吸顶方式通常可以通过来实现,但是 AppBarLayoutBehavior fling 无法传递到 NestedScrollView,快速来回滑动偶尔也会有些抖动,导致滚动不流畅。,那么就需要处理好 RecyclerView 的滑动冲突问题。

BASK2311的博客 1155

解决小程序在高层级页面滑动时,低层级页面会跟着滑动的问题

问题: 打开组件并上下滑动组件内容时,页面也会跟着滑动 解决方法:由于安卓和ios情况不同,所以用了两种方法,双保险. 1.当组件打开时,给整个页面设置height:100vh, overflow:hidden, 让页面高度占满屏幕并隐藏多余内容,这样页面就不会滚动了. 安卓系统做到这一步就可以解决了. 2.ios系统在完成第1步时,该问题还没有解决,是因为ios会有回弹效果. 所以在组件上添加一个无内容的@touchmove.stop="doNothing"滑动事件,就可以禁止下层页面滑动. 理论上来

Hope_wkx的博客 1557

html5两层叠加禁止底层滑动

//禁止滑动 $(document.body).css({ "overflow-x":"auto", "overflow-y":"auto" }); //开启滑动 $(document.body).css({ "overflow-x":"hidden", "overflow-y":"hidden" });

m0_37678565的博客 2470

Android 实现嵌套滑动

前言 Android实现简易滑动 上次文章中实现了简易的ScrollerView滑动,但实际使用中许多场景都会涉及到嵌套滑动,在今天的博文中我们基于上次的ScrollLayout来进一步实现嵌套滑动。 嵌套滑动预备知识:Android实现简易滑动 整体页面结构 <?xml version="1.0" encoding="utf-8"?> <com.example.nestedscroll.ScrollParentLayout xmlns:android="http://

放下矜持的博客 4840

Android 嵌套滑动总结

一、什么是嵌套滑动 嵌套滑动是 android 开发中常见的一种 UI 效果。当一个布局中包含多个可以滑动的 View,并且这些 View 互相嵌套的时候,就需要做嵌套滑动的处理来让 UI 交互有更流畅的效果,比如吸顶效果。常见的效果如下: 如上所示,最外层的父布局可以滑动,内层的 RecyclerView 也可以滑动。当上滑 RecyclerView 的时候,最外层的父布局先上滑,直到上滑到 tab 的时候,这时候 RecyclerView 开始滑动,父布局停止滑动,并且手指不需要离开屏幕,可以一次性完

zhireshini233的博客 1513

Android 嵌套滚动NestedScrollView+TabLayout+ViewPager+Fragment+RecyclerView 实现京东、美团首页效果Tab页滚动到顶部时自动吸附

Android 嵌套滚动NestedScrollView+TabLayout+ViewPager+Fragment+RecyclerView 实现京东、美团首页效果Tab页滚动到顶部时自动吸附

安卓开发-顺 的博客 4929

Android解决多层滑动嵌套滑动冲突问题

Android解决多层滑动嵌套滑动冲突

weixin_43117800的博客 718

安卓应用开发——Android Studio中滚动布局的应用

现如今,许多软件的主界面都采用了滚动条的功能,以展示软件中长条的商品又或是广告,经典的社交软件与购物软件等软件都不可避免的需要实现这一功能,今天我们来简单学习在AndroidStudio中实现一个属于自己的滚动布局页面。

2303_76399326的博客 1346
上一篇: 如何应对Android面试官->布局原理与xml解析,手写插件化换肤框架核心实现(下)
下一篇: Jetpack Compose -> 声明式UI & Modifier
老A说
博客等级 码龄14年 1181粉丝 85原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值