自定义Android侧滑菜单(模仿QQ侧滑效果)

Android自带的侧滑菜单  使用代码 如下

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    >
    <!--视图的主页面, 布局必须用FrameLayout-->
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/img2"
            />

    </FrameLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        >
        <!--android:layout_gravity="start"这行代码决定了菜单是从左侧划出还是从右侧滑出-->
        <Button
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="btn_test12222222"
            />

    </LinearLayout>



</android.support.v4.widget.DrawerLayout>

侧滑和主页面内容用按钮和图片代替了, 这样基本的侧滑功能就实现了

下面自定义来实现类似于QQ的侧边栏效果

新建 获取屏幕相关的辅助类 ScreenUtils , 直接贴代码了, 里面注释很详细

/**
 * 获得屏幕相关的辅助类
 *
 *
 */
public class ScreenUtils
{
    private ScreenUtils()
    {
        /* cannot be instantiated */
        throw new UnsupportedOperationException("cannot be instantiated");
    }

    /**
     * 获得屏幕高度
     *
     * @param context
     * @return
     */
    public static int getScreenWidth(Context context)
    {
        WindowManager wm = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        return outMetrics.widthPixels;
    }

    /**
     * 获得屏幕宽度
     *
     * @param context
     * @return
     */
    public static int getScreenHeight(Context context)
    {
        WindowManager wm = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        return outMetrics.heightPixels;
    }

    /**
     * 获得状态栏的高度
     *
     * @param context
     * @return
     */
    public static int getStatusHeight(Context context)
    {

        int statusHeight = -1;
        try
        {
            Class<?> clazz = Class.forName("com.android.internal.R$dimen");
            Object object = clazz.newInstance();
            int height = Integer.parseInt(clazz.getField("status_bar_height")
                    .get(object).toString());
            statusHeight = context.getResources().getDimensionPixelSize(height);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return statusHeight;
    }

    /**
     * 获取当前屏幕截图,包含状态栏
     *
     * @param activity
     * @return
     */
    public static Bitmap snapShotWithStatusBar(Activity activity)
    {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap bmp = view.getDrawingCache();
        int width = getScreenWidth(activity);
        int height = getScreenHeight(activity);
        Bitmap bp = null;
        bp = Bitmap.createBitmap(bmp, 0, 0, width, height);
        view.destroyDrawingCache();
        return bp;

    }

    /**
     * 获取当前屏幕截图,不包含状态栏
     *
     * @param activity
     * @return
     */
    public static Bitmap snapShotWithoutStatusBar(Activity activity)
    {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap bmp = view.getDrawingCache();
        Rect frame = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        int statusBarHeight = frame.top;

        int width = getScreenWidth(activity);
        int height = getScreenHeight(activity);
        Bitmap bp = null;
        bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height
                - statusBarHeight);
        view.destroyDrawingCache();
        return bp;

    }

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

    /**
     * Pixels converted into a dip
     */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }
}

在values下创建 attrs.xml 来指定 菜单与屏幕右边的距离

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="QQSlider">
        <!--菜单与屏幕右边的距离-->
        <attr name="qqMenuRightMargin" format="dimension"/>
    </declare-styleable>

</resources>

创建java类QQSlider ,直接上代码了, 里面注释很详细 

/**
 * desc:QQ侧滑效果
 */

public class QQSlider extends HorizontalScrollView {

    //左边菜单布局
    private View mLeftMenu;
    //内容布局
    private View mContentView;
    //菜单是否打开
    private boolean mMenuIsOpen;
    //是否拦截事件
    private boolean mIntercept;
    //手势处理类
    private GestureDetector mGestureDetector;
    //菜单的宽度
    private int mMenuWidth;
    private View mShadeView;
    private Context mContext;

    public QQSlider(Context context) {
        this(context,null);
    }

    public QQSlider(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public QQSlider(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.QQSlider);
        //菜单离右边屏幕边缘的距离
        float rightMargin = array.getDimension(R.styleable.QQSlider_qqMenuRightMargin, ScreenUtils.dip2px(mContext, 50));
        mMenuWidth = (int) (ScreenUtils.getScreenWidth(mContext) - rightMargin);
        array.recycle();
        mGestureDetector = new GestureDetector(mContext, mGestureDetectorListener);
    }

    private GestureDetector.SimpleOnGestureListener mGestureDetectorListener = new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            // 快速滑动
            // 向右快速滑动会是正的  +   向左快速滑动 是  -
            // 如果菜单是打开的   向右向左快速滑动都会回调这个方法
            if (mMenuIsOpen) {
                if (velocityX < 0) {
                    closeMenu();
                    return true;
                }
            } else {
                if (velocityX > 0) {
                    openMenu();
                    return true;
                }
            }
            return super.onFling(e1, e2, velocityX, velocityY);
        }
    };

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        //拿到根布局
        ViewGroup rootView = (ViewGroup) getChildAt(0);
        int childCount = rootView.getChildCount();
        if (childCount != 2)
            throw new RuntimeException("You can only place two sub view in the root");
        //拿到菜单布局
        mLeftMenu= rootView.getChildAt(0);
        //指定菜单的宽度
        ViewGroup.LayoutParams mLeftMenuLayoutParams = mLeftMenu.getLayoutParams();
        mLeftMenuLayoutParams.width = mMenuWidth;
        mLeftMenu.setLayoutParams(mLeftMenuLayoutParams);

        //拿到内容布局
        mContentView= rootView.getChildAt(1);
        //指定内容的宽度
        ViewGroup.LayoutParams mContentLayoutParams = mContentView.getLayoutParams();
        //把内容布局单读提出来
        rootView.removeView(mContentView);
        //在外面套一层阴影
        RelativeLayout contentContainer = new RelativeLayout(mContext);
        contentContainer.addView(mContentView);
        mShadeView = new View(mContext);
        mShadeView.setBackgroundColor(Color.parseColor("#55000000"));
        contentContainer.addView(mShadeView);
        //把容器放回去
        mContentLayoutParams.width = ScreenUtils.getScreenWidth(mContext);

        contentContainer.setLayoutParams(mContentLayoutParams);

        rootView.addView(contentContainer);
        mShadeView.setAlpha(0.0f);






    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        scrollTo(mMenuWidth,0);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        mIntercept = false;
        if (mMenuIsOpen) {
            float currentX = ev.getX();
            if (currentX > mMenuWidth) {
                //关闭菜单
                closeMenu();
                //子view不响应任何事件 拦截子view的触摸事件
                //如果返回true 代表会拦截子view的触摸事件,但是会相应自己的onTouch事件
                mIntercept = true;
                return true;
            }
        }
        return super.onInterceptTouchEvent(ev);
    }

    //3 事件的拦截处理
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        //获取手指滑动速率,获取手指滑动的速率,当期大于一定值就认为是快速滑动 , GestureDetector(系统提供好的类)
        //当菜单打开的时候,手指触摸右边内容部分需要关闭菜单,还需要拦截事件(打开情况下点击内容页不会响应点击事件)
        //这里保证了手势处理类的调用
        //快速滑动了 下面的拦截事件就不要处理了、
        if (mGestureDetector.onTouchEvent(ev)) {
            return true;
        }
        //如果有拦截,则不执行自己的onTouch方法
        if (mIntercept){
            return true;
        }
        // 拦截处理事件
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_UP:
                int currentScrollX = getScrollX();
                //在这里注意currentScrollX的变化,当我们默认关闭菜单的时候去拉动ScrollView,数值在不断的变小
                if (currentScrollX < mMenuWidth / 2) {
                    //打开菜单
                    openMenu();
                } else {
                    //关闭菜单
                    closeMenu();
                }
                //确保super.onTouchEvent不会执行 这里看super.onTouchEvent源码中的fling方法
                //和smoothScrollTo的源码
                return true;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 关闭菜单
     */
    private void closeMenu() {
        smoothScrollTo(mMenuWidth, 0);
        mMenuIsOpen = false;
    }

    /**
     * 打开菜单
     */
    private void openMenu() {
        smoothScrollTo(0, 0);
        mMenuIsOpen = true;
    }

    //4 处理主页内容的,这就需要不断的获取当前的滑动位置
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        //l是从mMuneWidth一直变化到0
        //计算梯度值
        float scale = 1f * l / mMenuWidth; //梯度从1逐渐变为0
        //控制阴影 从0变化到1
        float alphaScale = 1 -scale;
        mShadeView.setAlpha(alphaScale);

        ViewCompat.setTranslationX(mLeftMenu, 0.6f * l);

    }
}

在values下的 styles.xml新建一个主题 , 为了去掉标题栏, 防止标题栏影响侧滑效果

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <!--新建一个主题样式, 目的为了去掉标题栏-->
    <style name="AppThemeNoTitle" parent="AppTheme" >
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

</resources>

然后就可以使用了

新建一个侧滑菜单的布局  layout_slider_menu.xml , 这里面就是滑出的菜单的布局和里面的控件 , 根据需求指定

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/layout_menu_top"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        
        >
        <Button
            android:layout_width="match_parent"
            android:layout_height="match_parent" 
            android:text="这是侧滑菜单"
            />
        </LinearLayout>

</RelativeLayout>

创建一个Activity, SliderDemo

xml代码为: 

<?xml version="1.0" encoding="utf-8"?>
<com.lanyu96.qqsliderdemo.QQSlider
    android:layout_width="match_parent"
    android:background="#ffffff"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:qqMenuRightMargin="100dp"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
        <include layout="@layout/layout_slider_menu" />

        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/rl_content"
            android:background="#63d6cf"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="主页内容"
                android:textColor="@color/colorAccent"
                android:textSize="30sp" />

        </LinearLayout>
    </LinearLayout>

</>

还有一种效果就是 侧滑时, 主页布局 有缩放效果

QQSlider.java代码为 

/**
 * desc:QQ侧滑效果 , 带缩放效果
 */

public class QQSlider extends HorizontalScrollView {

    //左边的菜单
    private View mMenuView;
    //左边菜单布局
    private View mLeftMenu;
    //内容布局
    private View mContentView;
    //菜单是否打开
    private boolean mMenuIsOpen;
    //是否拦截事件
    private boolean mIntercept;
    //手势处理类
    private GestureDetector mGestureDetector;
    //菜单的宽度
    private int mMenuWidth;
    private View mShadeView;
    private Context mContext;

    public QQSlider(Context context) {
        this(context,null);
    }

    public QQSlider(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public QQSlider(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        mGestureDetector = new GestureDetector(mContext, new GestureDetectorListener());
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.QQSlider);
        float rightMargin = array.getDimension(R.styleable.QQSlider_qqMenuRightMargin, ScreenUtils.dip2px(mContext, 50));
        //菜单的宽度 = 屏幕的宽度-菜单离右边的距离
        mMenuWidth = (int) (ScreenUtils.getScreenWidth(mContext) - rightMargin);
        array.recycle();
    }

    /**
     * 手势处理的监听类
     */
    private class GestureDetectorListener extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            // 快速滑动
            // 向右快速滑动会是正的  +   向左快速滑动 是  -
            // 如果菜单是打开的   向右向左快速滑动都会回调这个方法
            if (mMenuIsOpen) {
                if (velocityX < 0) {
                    closeMenu();
                    return true;
                }
            } else {
                if (velocityX > 0) {
                    openMenu();
                    return true;
                }
            }
            return false;
        }
    }

    /**
     * 1.这个方法在整个布局xml解析完毕走这个方法
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        //获取菜单和主页内容
        //我们在这里getChildAt(0)拿的是我们布局中的LinearLayout
        ViewGroup container = (ViewGroup) getChildAt(0);
        int childCount = container.getChildCount();
        if (childCount != 2) {
            //抛运行时异常,只能放置两个子view
            throw new RuntimeException("You can only place two sub view");
        }
        //拿到我们的菜单布局
        mMenuView = container.getChildAt(0);
        //拿到我们的主页内容的布局
        mContentView = container.getChildAt(1);
        ViewGroup.LayoutParams layoutMenuParams = mMenuView.getLayoutParams();
        //指定菜单的宽度
        layoutMenuParams.width = mMenuWidth;
        //7.0
        mMenuView.setLayoutParams(layoutMenuParams);
        ViewGroup.LayoutParams layoutContentParams = mContentView.getLayoutParams();
        //指定内容的宽度 指定宽高后会重新摆放 在onLayout中
        layoutContentParams.width = ScreenUtils.getScreenWidth(mContext);
        mContentView.setLayoutParams(layoutContentParams);
    }

    //2 布局摆放 默认进来进来是关闭的
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        // 用来排放子布局的   等子View全部摆放完才能去滚动 我们一进来的时候默认是关闭菜单的
        //类比纵向的ScrollVew的来理解
        scrollTo(mMenuWidth, 0);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        mIntercept = false;
        if (mMenuIsOpen) {
            float currentX = ev.getX();
            if (currentX > mMenuWidth) {
                //关闭菜单
                closeMenu();
                //子view不响应任何事件 拦截子view的触摸事件
                //如果返回true 代表会拦截子view的触摸事件,但是会相应自己的onTouch事件
                mIntercept = true;
                return true;
            }
        }
        return super.onInterceptTouchEvent(ev);
    }

    //3 事件的拦截处理
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        //获取手指滑动速率,获取手指滑动的速率,当期大于一定值就认为是快速滑动 , GestureDetector(系统提供好的类)
        //当菜单打开的时候,手指触摸右边内容部分需要关闭菜单,还需要拦截事件(打开情况下点击内容页不会响应点击事件)
        //这里保证了手势处理类的调用
        //快速滑动了 下面的拦截事件就不要处理了、
        if (mGestureDetector.onTouchEvent(ev)) {
            return true;
        }
        //如果有拦截,则不执行自己的onTouch方法
        if (mIntercept){
            return true;
        }
        // 拦截处理事件
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_UP:
                int currentScrollX = getScrollX();
                //在这里注意currentScrollX的变化,当我们默认关闭菜单的时候去拉动ScrollView,数值在不断的变小
                if (currentScrollX < mMenuWidth / 2) {
                    //打开菜单
                    openMenu();
                } else {
                    //关闭菜单
                    closeMenu();
                }
                //确保super.onTouchEvent不会执行 这里看super.onTouchEvent源码中的fling方法
                //和smoothScrollTo的源码
                return true;
        }
        return super.onTouchEvent(ev);
    }


    //4 处理主页内容的缩放,左边的缩放和透明度的调节 这就需要不断的获取当前的滑动位置
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        //l是从mMuneWidth一直变化到0
        //计算梯度值
        float scale = 1f * l / mMenuWidth; //梯度从1逐渐变为0
        //右边的缩放 最小0.7f 最大是1
        float rightScale = 0.7f + 0.3f * scale;
        //设置主页内容的缩放,默认是中心点缩放
        //设置缩放的中心点
        ViewCompat.setPivotX(mContentView, 0);
        ViewCompat.setPivotY(mContentView, mContentView.getMeasuredHeight() / 2);
        ViewCompat.setScaleX(mContentView, rightScale);
        ViewCompat.setScaleY(mContentView, rightScale);

        //设置菜单的缩放和透明度 从半透明到完全透明 0.5f到1.0f
        float menuAlpha = 0.5f + (1 - scale) * 0.5f;
        ViewCompat.setAlpha(mMenuView, menuAlpha);
        //缩放处理
        float menuScale = 0.7f + (1 - scale) * 0.3f;
        ViewCompat.setScaleX(mMenuView, menuScale);
        ViewCompat.setScaleY(mMenuView, menuScale);
        //设置平移 l*0.7f
        ViewCompat.setTranslationX(mMenuView, 0.25f * l);


    }

    /**
     * 关闭菜单
     */
    private void closeMenu() {
        smoothScrollTo(mMenuWidth, 0);
        mMenuIsOpen = false;
    }

    /**
     * 打开菜单
     */
    private void openMenu() {
        smoothScrollTo(0, 0);
        mMenuIsOpen = true;
    }
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现Android侧滑菜单有多种方式,其中一种比较常见的实现方式是使用DrawerLayout和NavigationView。 步骤如下: 1. 在XML布局文件中添加DrawerLayout和NavigationView,其中NavigationView中可以添加菜单项。 ``` <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 主界面内容 --> <FrameLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" /> <!-- 侧滑菜单 --> <android.support.design.widget.NavigationView android:id="@+id/navigation_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header" app:menu="@menu/nav_menu" /> </android.support.v4.widget.DrawerLayout> ``` 2. 在Activity中设置DrawerLayout和NavigationView的监听器,并在onOptionsItemSelected方法中处理菜单项点击事件。 ``` public class MainActivity extends AppCompatActivity { private DrawerLayout mDrawerLayout; private NavigationView mNavigationView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mDrawerLayout = findViewById(R.id.drawer_layout); mNavigationView = findViewById(R.id.navigation_view); mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { // 处理菜单项点击事件 return false; } }); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, mDrawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); mDrawerLayout.addDrawerListener(toggle); toggle.syncState(); } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == android.R.id.home) { mDrawerLayout.openDrawer(GravityCompat.START); return true; } return super.onOptionsItemSelected(item); } } ``` 3. 在NavigationView中添加菜单项,并为菜单项设置图标和标题。 ``` <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single"> <item android:id="@+id/nav_home" android:icon="@drawable/ic_home" android:title="Home" /> <item android:id="@+id/nav_gallery" android:icon="@drawable/ic_gallery" android:title="Gallery" /> <item android:id="@+id/nav_slideshow" android:icon="@drawable/ic_slideshow" android:title="Slideshow" /> </group> </menu> ``` 至此,实现了一个简单的Android侧滑菜单。如果要实现仿QQ侧滑删除功能,可以在ListView或RecyclerView中添加滑动删除的功能,并在删除时更新侧滑菜单中的未读消息数等信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值