Android笔记

声明:本文为个人学习笔记,内容大多来自哔哩哔哩视频和《第一行代码》以及Android Developer官网,如有侵权请联系E-mail:YAMA

常见单位

dip(同dp):(density independence pixel)设备独立像素,不同设备有不同的显示效果,这一般,不依赖像素
px: pixels不同设备显示效果相同
pt: point,是一个标准的长度单位,1pt=1/72英寸,用于印刷业,非常简单易用
sp: scaled pixels(缩放像素). 主要用于字体显示best for textsize。

示例代码

<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"
    tools:context=".MainActivity"
    android:gravity="center"
    android:background="#8fffad">

    <TextView
        android:id="@+id/txtOne"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:gravity="center"
        android:text="TextView(显示框)"
        android:textColor="#EA5246"
        android:textStyle="bold|italic"
        android:background="#000000"
        android:textSize="18sp" />

</RelativeLayout>

上面代码中有几个属性

  • id:为TextView设置一个id,类比前端,可以在Java代码中通过findViewById()的方法获取到该对象,然后进行相关属性的设置,又或者使用RelativeLayout(线性)时,参考组件用的也是id
  • layout_width:组件的宽度,一般写:wrap_content或者match_parent(fill_parent),前者是控件显示的内容多大,控件就多大(类比html中的inline型元素),而后者会填满该控件所在的父容器;当然也可以设置成特定的大小。对于match_parent和fill_parent存在区别
  • gravity:设置控件中内容的对齐方向,TextView中是文字,ImageView中是图片等等。
  • text:设置显示的文本内容,一般我们是把字符串写到string.xml文件中,然后通过@String/xxx取得对应的字符串内容的,这里为了方便我直接就写到""里,不建议这样写!
  • textColor:设置字体颜色,同上,通过colors.xml资源来引用,别直接这样写!
  • textStyle:设置字体风格,三个可选值:normal(无效果),bold(加粗),italic(斜体)
  • textSize:字体大小,单位一般是用sp
  • background:控件的背景颜色,可以理解为填充整个控件的颜色,可以是图片哦!
    view中的layout_width形容的是本view和父容器的关系;而view中的width是用来描述自己本身的
  • android:width 的值,一般是 “100dp” 这样的数值;
  • android:layout_width 的值,一般是"fill_parent",“wrap_content”,“match_parent”.当然,它也可以像前者一样,设置数值的。
  • android:layout_width 其实是可以实现 android:width 的效果的,我觉得这应该是为什么在 android 实例中看不到有人用 android:width 的原因吧。
    带"layout"的属性是指整个控件而言的,是与父控件之间的关系,如 layout_gravity 在父控件中的对齐方式, layout_margin 是级别相同的控件之间的间隙等等;不带"layout" 的属性是指控件中文本的格式,如gravity是指文本的对齐方式等等,而其中文本的格式又受制约于它的控件在父控件中的属性
  • android:shadowColor:设置阴影颜色,需要与shadowRadius一起使用哦!
  • android:shadowRadius:设置阴影的模糊程度,设为0.1就变成字体颜色了,建议使用3.0
  • android:shadowDx:设置阴影在水平方向的偏移,就是水平方向阴影开始的横坐标位置
  • android:shadowDy:设置阴影在竖直方向的偏移,就是竖直方向阴影开始的纵坐标位置
  • <solid android:color = "xxx"> 这个是设置背景颜色的
    `
  • `这个是设置边框的粗细,以及边框颜色的
  • <padding androidLbottom = "xdp"...>这个是设置边距的
  • <corners android:topLeftRadius="10px"...> 这个是设置圆角的
  • <gradient> 这个是设置渐变色的,可选属性有: startColor:起始颜色 endColor:结束颜色 centerColor:中间颜色 angle:方向角度,等于0时,从左到右,然后逆时针方向转,当angle = 90度时从下往上 type:设置渐变的类型
  • horizontally→水平
  • vertically→垂直

    点击查看教程

在开发中要学会使用辅助线,因为不同的设备运行效果可能有所不同,辅助线可以按照百分比划分尺寸,可以有效解决某些显示相关问题

四大组件

Android系统四大组件分别是活动(Activity)、服务(Service)、广播接收器(Broadcast
Receiver)和内容提供器(Content Provider)。其中活动是所有Android应用程序的门面,凡
是在应用中你看得到的东西,都是放在活动中的。而服务就比较低调了,你无法看到它,
但它会一直在后台默默地运行,即使用户退出了应用,服务仍然是可以继续运行的。广播
接收器允许你的应用接收来自各处的广播消息,比如电话、短信等,当然你的应用同样也
可以向外发出广播消息。内容提供器则为应用程序之间共享数据提供了可能,比如你想要
读取系统电话簿中的联系人,就需要通过内容提供器来实现。

Project项目结构

  1. .gradle和.idea
    这两个目录下放置的都是Android Studio自动生成的一些文件,我们无须关心,也不要去手动编辑。
  2. app
    项目中的代码、资源等内容几乎都是放置在这个目录下的,我们后面的开发工作也基本都是在这个目录下进行的,待会儿还会对这个目录单独展开进行讲解。
  3. build
    这个目录你也不需要过多关心,它主要包含了一些在编译时自动生成的文件。
  4. gradle
    这个目录下包含了gradle wrapper的配置文件,使用gradle wrapper的方式不需要提前将gradle下载好,而是会自动根据本地的缓存情况决定是否需要联网下载gradle。Android Studio默认没有启用gradle wrapper的方式,如果需要打开,可以点击Android Studio导航栏→File→Settings→Build, Execution,Deployment→Gradle,进行配置更改。
  5. .gitignore
    这个文件是用来将指定的目录或文件排除在版本控制之外的,关于版本控制我们将在第5章中开始正式的学习。
  6. build.gradle
    这是项目全局的gradle构建脚本,通常这个文件中的内容是不需要修改的。稍后我们将会详细分析gradle构建脚本中的具体内容。
  7. gradle.properties
    这个文件是全局的gradle配置文件,在这里配置的属性将会影响到项目中所有的gradle编译脚本。
  8. gradlew和gradlew.bat
    这两个文件是用来在命令行界面中执行gradle命令的,其中gradlew是在Linux或Mac系统中使用的,gradlew.bat是在Windows系统中使用的。
  9. HelloWorld.iml
    iml文件是所有IntelliJ IDEA项目都会自动生成的一个文件(Android Studio是基于IntelliJIDEA开发的),用于标识这是一个IntelliJ IDEA项目,我们不需要修改这个文件中的任何内容。
  10. local.properties
    这个文件用于指定本机中的Android SDK路径,通常内容都是自动生成的,我们并不需要修改。除非你本机中的Android SDK位置发生了变化,那么就将这个文件中的路径改成新的位置即可。
  11. settings.gradle
    这个文件用于指定项目中所有引入的模块。由于HelloWorld项目中就只有一个app模块,因此该文件中也就只引入了app这一个模块。通常情况下模块的引入都是自动完成的,需要我们手动去修改这个文件的场景可能比较少。

除了app目录之外,大多数的文件和目录都是自动生成的,我们并不需要进行修改。想必你已经猜到了,app目录下的内容才是我们以后的工作重点,

app目录结构

  1. build这个目录和外层的build目录类似,主要也是包含了一些在编译时自动生成的文件,不过它里面的内容会更多更杂,我们不需要过多关心。
  2. libs如果你的项目中使用到了第三方jar包,就需要把这些jar包都放在libs目录下,放在这个目录下的jar包都会被自动添加到构建路径里去。
  3. androidTest此处是用来编写Android Test测试用例的,可以对项目进行一些自动化测试
  4. java毫无疑问,java目录是放置我们所有Java代码的地方,展开该目录,你将看到我们刚才创建的HelloWorldActivity文件就在里面。
  5. res这个目录下的内容就有点多了。简单点说,就是你在项目中使用到的所有图片、布局、字符串等资源都要存放在这个目录下。当然这个目录下还有很多子目录,图片放在drawable目录下,布局放在layout目录下,字符串放在values目录下,所以你不用担心会把整个res目录
    弄得乱糟糟的。
  6. AndroidManifest.xml这是你整个Android项目的配置文件,你在程序中定义的所有四大组件都需要在这个文件里注册,另外还可以在这个文件中给应用程序添加权限声明。由于这个文件以后会经常用到,我们用到的时候再做详细说明。
  7. test此处是用来编写Unit Test测试用例的,是对项目进行自动化测试的另一种方式。
  8. gitignore这个文件用于将app模块内的指定的目录或文件排除在版本控制之外,作用和外层的.gitignore文件类似。
  9. app.imlIntelliJ IDEA项目自动生成的文件,我们不需要关心或修改这个文件中的内容
  10. build.gradle这是app模块的gradle构建脚本,这个文件中会指定很多项目构建相关的配置,我们稍后将会详细分析gradle构建脚本中的具体内容。
  11. proguard-rules.pro这个文件用于指定项目代码的混淆规则,当代码开发完成后打成安装包文件,如果不希望代码被别人破解,通常会将代码进行混淆,从而让破解者难以阅读。

res目录结构

drawable开头的文件夹都是用来放图片的
mipmap开头的文件夹都是用来放应用图标的
values开头的文件夹都是用来放字符串、样式、颜色等配置的
layout文件夹是用来放布局文件的。
之所以有这么多mipmap开头的文件夹,其实主要是为了让程序能够更好地兼容各种设备。drawable文件夹也是相同的道理,虽然Android Studio没有帮我们自动生成,但是我们应该自己创建drawable-hdpi、drawable-xhdpi、drawable-xxhdpi等文件夹。在制作程序的时候最好能够给同一张图片提供几个不同分辨率的版本,分别放在这些文件夹下,然后当程序运行的时候,会自动根据当前运行设备分辨率的高低选择加载哪个文件夹下的图片。当然这只是理想情况,更多的时候美工只会提供给我们一份图片,这时你就把所有图片都放在drawable-xxhdpi文件夹下就好了
比如,在此文件夹下AndroidStudioProjects\Hello_world\app\src\main\res\values\strings.xml中

<resources>
    <string name="foo">你好!</string>
</resources>

我们可以通过两种方式获得它的引用

  • 代码中通过R.string.app_name可以获得该字符串的引用
  • XML中通过@string/app_name可以获得该字符串的引用

Androidmanifest.xml文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.hello_world">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

<activity android:name=".MainActivity">这段代码对MainActivity这个活动进行注册,其中中intent-filter里的两行代码非常重要,
<action android:name="android.intent.action.MAIN" />

<categoryandroid:name="android.intent.category.LAUNCHER" />
表示HelloWorldActivity是这个项目的主活动,在手机上点击应用图标,首先启动的就是这个活动。

build.gradle文件

通常情况下你并不需要修改这个文件中的内容,除非你想添加一些全局的项目构建配置。

// 顶级构建文件,您可以在其中添加所有子项目/模块共有的配置选项。
buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        //声明了gradle插件
        classpath 'com.android.tools.build:gradle:3.4.1' 
     //注意:请勿在此处放置应用程序依赖项; 他们属于在各个模块的build.gradle文件中
    }
}
allprojects {
    repositories {
        google()
        jcenter()
    }
}
task clean(type: Delete) {
    delete rootProject.buildDir
}

jcenter() 是什么?其实它是一个代码托管仓库,很多Android开源项目都会选择将代码托管到jcenter上,声明了这行配置之后,我们就可以在项目中轻松引用任何jcenter上的开源项目了。

app下的build.gradle文件

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.example.hello_world"
        minSdkVersion 15
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
  • 首先第一行应用了一个插件,一般有两种值可选:
    com.android.application表示这是一个应用程序模块
    com.android.library表示这是一个库模块
    应用程序模块和库模块的最大区别在于,一个是可以直接运行的,一个只能作为代码库依附于别的应用程序模块来运行。
  • 接下来是一个android闭包,在这个闭包中我们可以配置项目构建的各种属性。
    1. compileSdkVersion用于指定项目的编译版本,这里指定成29表示使用Android 9.0系统的SDK编译
    2. buildToolsVersion用于指定项目构建工具的版本,目前最新的版本就是29.0.2,如果有更新的版本时,Android Studio会进行提示
    3. 在android闭包中又嵌套了一个defaultConfig闭包,defaultConfig闭包中可以对项目的更多细节进行配置。其中
      • applicationId用于指定项目的包名,前面我们在创建项目的时候其实已经指定过包名了,如果你想在后面对其进行修改,那么就是在这里修改的
      • minSdkVersion用于指定项目最低兼容的Android系统版本,这里指定成15表示最低兼容到Android 4.0系统
      • targetSdkVersion指定的值表示你在该目标版本上已经做过了充分的测试,系统将会为你的应用程序启用一些最新的功能和特性。比如说Android 6.0系统中引入了运行时权限这个功能,如果你将targetSdkVersion指定成23或者更高,那么系统就会为你的程序启用运行时权限功能,而如果你将targetSdkVersion指定成22,那么就说明你的程序最高只在Android 5.1系统上做过充分的测试,Android 6.0系统中引入的新功能自然就不会启用了。剩下的两个属性都比较简单
      • versionCode用于指定项目的版本号
      • versionName用于指定项目的版本名,这两个属性在生成安装文件的时候非常重要
    4. 接下来我们看一下buildTypes闭包buildTypes闭包中用于指定生成安装文件的相关配置,通常只会有两个子闭包,一个是debug,一个是release。
      • debug闭包用于指定生成测试版安装文件的配置,debug闭包是可以忽略不写
      • release闭包用于指定生成正式版安装文件的配置。
        下面来看一下release闭包中的具体内容吧
        • minifyEnabled用于指定是否对项目的代码进行混淆,true表示混淆,false表示不混淆。
        • proguardFiles用于指定混淆时使用的规则文件,这里指定了两个文件,第一个proguard-android.txt是在Android SDK目录下的,里面是所有项目通用的混淆规则,第二个proguard-rules.pro是在当前项目的根目录下的,里面可以编写当前项目特有的混淆规则。需要注意的是,通过Android Studio直接运行项目生成的都是测试版安装文件,关于如何生成正式版安装文件我们将会在第15章中学习。
  • 下来还剩一个dependencies闭包。这个闭包的功能非常强大,它可以指定当前项目所有的依赖关系。通常Android Studio项目一共有3种依赖方式:本地依赖、库依赖和远程依赖。本地依赖可以对本地的Jar包或目录添加依赖关系,库依赖可以对项目中的库模块添加依赖关系,远程依赖则可以对jcenter库上的开源项目添加依赖关系。观察一下dependencies闭包中的配置,第一行的compile fileTree就是一个本地依赖声明,它表示将libs目录下所有.jar后缀的文件都添加到项目的构建路径当中。而第二行的compile则是远程依赖声明,com.android.support:appcompat-v7:24.2.1就是一个标准的远程依赖库格式,其中com.android.support是域名部分,用于和其他公司的库做区分;appcompat-v7是组名称,用于和同一个公司中不同的库做区分;24.2.1是版本号,用于和同一个库不同的版本做区分。加上这句声明后,Gradle在构建项目时会首先检查一下本地是否已经有这个库的缓存,如果没有的话则会去自动联网下载,然后再添加到项目的构建路径当中。至于库依赖声明这里没有用到,它的基本格式是compile project后面加上要依赖的库名称,比如说有一个库模块的名字叫helper,那么添加这个库的依赖关系只需要加入compileproject(’:helper’)这句声明即可。另外剩下的一句testCompile是用于声明测试用例库的,这个我们暂时用不到,先忽略它就可以了。

Logcat→日志猫的使用

  • Log.v()。用于打印那些最为琐碎的、意义最小的日志信息。对应级别verbose,是Android日志里面级别最低的一种。
  • Log.d()。用于打印一些调试信息,这些信息对你调试程序和分析问题应该是有帮助的。对应级别debug,比verbose高一级。
  • Log.i()。用于打印一些比较重要的数据,这些数据应该是你非常想看到的、可以帮你分析用户行为数据。对应级别info,比debug高一级。
  • Log.w()。用于打印一些警告信息,提示程序在这个地方可能会有潜在的风险,最好去修复一下这些出现警告的地方。对应级别warn,比info高一级。
  • Log.e()。用于打印程序中的错误信息,比如程序进入到了catch语句当中。当有错误信息打印出来的时候,一般都代表你的程序出现严重问题了,必须尽快修复。对应级别error,比warn高一级。
    一共就5个方法,当然每个方法还会有不同的重载
    比如Log.d(TAG, "onCreate: ");
    TAG可以是自己定义的String变量,一般传入当前的类名就好,主要用于对打印信息进行过滤;第二个参数是要打印的具体内容。在logcat中查看:打印日志的内容和tag名,就连程序的包名、打印的时间以及应用程序的进程号都可以看到
2019-11-30 10:08:27.714 26181-26181/com.example.hello_world V/mytag: onResume: 
2019-11-30 10:08:27.813 26181-26181/com.example.hello_world D/mytag: onPause:

对于输出信息我想到的是Java的System.out,不过在此处和log比起来,它明显不能胜任,比如日志打印不可控制、打印时间无法确定、不能添加过滤器、日志没有级别区分,log恰好弥补了这些缺点,同时在Android Studio输入log+?按回车便可快捷输入十分方便。如果在onCreate()方法的外面输入logt,回车,这时就会以当前的类名作为值自动生成一个TAG常量,贼方便。
在底部工具栏我们可以自己设置一个过滤器,如图其中data就是自己定义的

同时可以在选择日志级别,日志级别控制的好处就是,你可以很快地找到你所关心的那些日志。比如而现在你只需要将日志级别选中为error,那些不相干的琐碎信息就不会再干扰你的视线

还可以设置关键字过滤 (支持正则表达式)

Android程序的逻辑和视图分离

不推荐在活动中直接编写界面的,更加通用的一种做法是,在布局文件中编写界面,然后在活动中引入进来。可以看到,在onCreate()方法的第二行调用了setContentView()方法,就是这个方法给当前的活动引入了一个hello_world_layout布局。
比如对于字符串资源我们一般都写到strings.xml中,而不是直接写到函数里面

Android四大组件

图片源自https://developer.android.google.cn/guide/platform,在《第一行代码中》也有讲到这点。不过现在Android的官网上已经由四层增加到了五层,如图

1、Linux内核层

Android 平台的基础是 Linux 内核。例如,Android Runtime (ART) 依靠 Linux 内核来执行底层功能,例如线程和低层内存管理。这一层为Android设备的各种硬件提供了底层的驱动,如显示驱动、音频驱动、照相机驱动、蓝牙驱动、Wi-Fi驱动、电源管理等。使用 Linux 内核可让 Android 利用主要安全功能,并且允许设备制造商为著名的内核开发硬件驱动程序。

2、硬件抽象层(HAL)

硬件抽象层 (HAL) 提供标准界面,向更高级别的 Java API 框架显示设备硬件功能。HAL 包含多个库模块,其中每个模块都为特定类型的硬件组件实现一个界面,例如相机或蓝牙模块。当框架 API 要求访问设备硬件时,Android 系统将为该硬件组件加载库模块。

3、Android Runtime + 原生 C/C++ 库

Android Runtime:
对于运行 Android 5.0(API 级别 21)或更高版本的设备,每个应用都在其自己的进程中运行,并且有其自己的 Android Runtime (ART) 实例。ART 编写为通过执行 DEX 文件在低内存设备上运行多个虚拟机,DEX 文件是一种专为 Android 设计的字节码格式,经过优化,使用的内存很少。编译工具链(例如 Jack)将 Java 源代码编译为 DEX 字节码,使其可在 Android 平台上运行。
ART 的部分主要功能包括:
预先 (AOT) 和即时 (JIT) 编译
优化的垃圾回收 (GC)
在 Android 9(API 级别 28)及更高版本的系统中,支持将应用软件包中的 Dalvik Executable 格式 (DEX) 文件转换为更紧凑的机器代码。
更好的调试支持,包括专用采样分析器、详细的诊断异常和崩溃报告,并且能够设置观察点以监控特定字段
在 Android 版本 5.0(API 级别 21)之前,Dalvik 是 Android Runtime。如果您的应用在 ART 上运行效果很好,那么它应该也可在 Dalvik 上运行,但反过来不一定。
Android 还包含一套核心运行时库,可提供 Java API 框架所使用的 Java 编程语言中的大部分功能,包括一些 Java 8 语言功能。

原生 C/C++ 库:
许多核心 Android 系统组件和服务(例如 ART 和 HAL)构建自原生代码,需要以 C 和 C++ 编写的原生库。Android 平台提供 Java 框架 API 以向应用显示其中部分原生库的功能。例如,您可以通过 Android 框架的 Java OpenGL API 访问 OpenGL ES,以支持在应用中绘制和操作 2D 和 3D 图形。
如果开发的是需要 C 或 C++ 代码的应用,可以使用 Android NDK 直接从原生代码访问某些原生平台库。

4、Java API Framework

您可通过以 Java 语言编写的 API 使用 Android OS 的整个功能集。这些 API 形成创建 Android 应用所需的构建块,它们可简化核心模块化系统组件和服务的重复使用,包括以下组件和服务:

  • 丰富、可扩展的视图系统,可用以构建应用的 UI,包括列表、网格、文本框、按钮甚至可嵌入的网络浏览器
  • 资源管理器,用于访问非代码资源,例如本地化的字符串、图形和布局文件
  • 通知管理器,可让所有应用在状态栏中显示自定义提醒
  • Activity 管理器,用于管理应用的生命周期,提供常见的导航返回栈
  • 内容提供程序,可让应用访问其他应用(例如“联系人”应用)中的数据或者共享

其自己的数据开发者可以完全访问 Android 系统应用使用的框架 API。

5、System Apps

Android 随附一套用于电子邮件、短信、日历、互联网浏览和联系人等的核心应用。平台随附的应用与用户可以选择安装的应用一样,没有特殊状态。因此第三方应用可成为用户的默认网络浏览器、短信 Messenger 甚至默认键盘(有一些例外,例如系统的“设置”应用)。

系统应用可用作用户的应用,以及提供开发者可从其自己的应用访问的主要功能。例如,如果您的应用要发短信,您无需自己构建该功能,可以改为调用已安装的短信应用向您指定的接收者发送消息。

活动切换

首先最起码得由两个Activity,在程序启动的主Activity添加如下代码

btn = findViewById(R.id.button4);
btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(MainActivity.this,SecondActivity.class);
        startActivity(intent);
    }
});

当你点击主Activity中的button就切换到了第二个Activity,点击系统自带的就可以返回主Activity

Activity生命周期

我的理解:在由当前视图切换到另一视图时,当前Activity会onPause→onStop
当切换回来会onRestart→onStart→onResume:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值