Android 5.0 6.0 7.0 8.0 9.0 新特性

下面总结下从5.0到9.0包含的主要新特性

5.0 新特性  (Android5.0 API)  


 1、动态替换Theme  

        ##1、 MaterialTheme配色方案:http://www.materialpalette.com
       ##2、 
修改状态栏,ActionBar,界面背景,NavigationBar的颜色。让Activity使用自定义的Theme

<style name="AppTheme" parent="@android:style/Theme.Material">
    <!--状态栏颜色-->
    <item name="android:colorPrimaryDark">#f00</item>
    <!--ActionBar颜色-->
    <item name="android:colorPrimary">#ff0</item>
    <!--界面背景颜色-->
    <item name="android:windowBackground">@color/colorWindowBackground</item>
    <!--导航栏颜色-->
    <item name="android:navigationBarColor">#00f</item>
</style>

     ##3、 动态替换Theme的步骤:  
          * 定义至少2套theme
          * 调用setTheme方法设置当前的theme,但是该方法要在setContentView之前,如:
                 setTheme(mTheme);
                setContentView(R.layout.activity_main);
          * 设置了Theme,需要finish当前Activity,然后重启当前Activity,让Theme生效
                   Intent intent = getActivity().getIntent();
                   getActivity().finish();//结束当前的Activity
                   getActivity().overridePendingTransition(0,0);//不要动画
                   startActivity(intent);

   2、水波纹动画,自定义水波纹动画以及状态选择器动画

        ##1、 首先,在Android5.0以上,点击效果默认自带水波纹效果,并且有2种选择:

//矩形边框水波纹
android:background="?android:attr/selectableItemBackground"
//无边框限制水波纹
android:background="?android:attr/selectableItemBackgroundBorderless"

     ##2、 自定义水波纹动画
         使用ViewAnimationUtils创建圆形水波纹动画,注意该动画不能在Activity的onCreate方法中执行:

Animator circularReveal = ViewAnimationUtils.createCircularReveal(text, 0, text.getHeight() , 1f, text.getWidth()*2);
circularReveal.setDuration(1000);
circularReveal.start();

使用ripple标签或者RippleDrawable可以更改控件水波纹动画颜色:

<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="#00ff00">
<item android:id="@android:id/mask" ><color android:color="#0000ff" />

3、CardViewd的使用

CardLayout拥有高度和阴影,以及轮廓裁剪,圆角等功能  (CardView的解析

1.设置圆角:card_view:cardCornerRadius="10dp"
2.设置高度:card_view:cardElevation="10dp"
3.设置内边距:card_view:contentPadding="10dp"
4.设置背景色:card_view:cardBackgroundColor="?android:attr/colorPrimary"

4、RecyclerView的使用
   
 RecyclerView与ListView比较

    ##1、 先添加依赖 compile 'com.android.support:recyclerview-v7:23.1.1'
    ##2、 设置LayoutManager:控制RecyclerView如何显示布局,系统提供3个布局管理器:
           LinearLayoutManager:线性布局,有横向和竖直方向显示
           GridLayoutManager:网格布局,有横向和竖直方向显示
           StaggeredGridLayoutManager: 瀑布流布局,有横向和竖直方向显示
   ##3、 然后给RecyclerView设置Adapter<RecyclerView.ViewHolder>
   ##4、 设置点击事件,由于RecyclerView没有setOnItemClickListener,只能在Adapter中给View设置Click事件

5、ToolBar的使用
      ##1、它用来代替ActionBar,但是比ActionBar更加灵活,相当于可以写在布局文件中的ActionBar;与DrawerLayout的使用的时候,DrawerLayout可以覆盖在ToolBar上,并且ToolBar和ActionBar不能同时使用
      ##2、使用ToolBar的步骤:
            *先隐藏ActionBar,可以继承一个不带ActionBar的Theme,如:             
                  style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"
            *然后在Activity中设置ToolBar替代ActionBar:
                  setSupportActionBar(toolBar);
            * 最后设置ToolBar的显示内容:
                toolBar.setTitle("ToolBar");//设置标题
                toolBar.setNavigationIcon(iconRes);//设置图标
                toolBar.setOnMenuItemClickListener();//设置Menu Item点击

6、SwipeRefreshLayout的使用
     ##1、添加依赖   compile 'com.android.support:appcompat-v7:23+'
    ##2、布局文件中使用

<android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/refreshLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!">

##3、在MainActivy设置,下拉刷新的回调即可

mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
    @Override
    public void onRefresh() {
        //模拟网络请求需要3000毫秒,请求完成,设置setRefreshing 为false
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                mSwipeRefreshLayout.setRefreshing(false);
            }
        }, 3000);
    }
});

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

##4、用法知识点进阶

//设置进度View样式的大小,只有两个值DEFAULT和LARGE
mSwipeRefreshLayout.setSize(mSetSizeBean.size);
//设置进度View下拉的起始点和结束点,scale 是指设置是否需要放大或者缩小动画
mSwipeRefreshLayout.setProgressViewOffset(true, -0, 100);
//设置进度View下拉的结束点,scale 是指设置是否需要放大或者缩小动画
mSwipeRefreshLayout.setProgressViewEndTarget(true, 180);
//设置进度View的组合颜色,在手指上下滑时使用第一个颜色,在刷新中,会一个个颜色进行切换
mSwipeRefreshLayout.setColorSchemeColors(Color.BLACK, Color.GREEN, Color.RED, Color.YELLOW, Color.BLUE);

//设置触发刷新的距离
mSwipeRefreshLayout.setDistanceToTriggerSync(200);
//如果child是自己自定义的view,可以通过这个回调,告诉mSwipeRefreshLayoutchild是否可以滑动
mSwipeRefreshLayout.setOnChildScrollUpCallback(null);


6.0新特性6.0 API


1、TextInputLayout的使用
    ##1、使用需要依赖design类库:
          compile 'com.android.support:design:23.0.0+'
    ##2、使用步骤
         * 先在TextInputLayout中包裹一个EditText
         * 然后给EditText添加文本变化监听器

editText.addTextChangedListener(new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
public void afterTextChanged(Editable s) {
    if(s.length() > 5){
        //设置错误提示信息
        inputLayout.setError("不能超过5个");
        //启用错误提示
        inputLayout.setErrorEnabled(true);
    }else{
        //关闭错误提示
        inputLayout.setErrorEnabled(false);
    }
  }
});

2、FloatingActionButton的使用
    ##1、使用需要依赖design类库:
        compile 'com.android.support:design:23.0.0+'
    ##2、设置以下属性
         app:fabSize="normal"//2个取值,normal=56dp,mini=48dp
         app:elevation="10dp"//高度
         app:rippleColor="#0000ff"//按下水波纹颜色
         app:pressedTranslationZ="20dp"//按下Z轴移动距离 注意:设置android:clickable="true"才有按下的效果

3、TabLayout的使用
   ##1、相当于ViewPagerIndicator的指示器效果,一般用来跟ViewPager结合使用
   ##2、使用需要依赖design类库:
        compile 'com.android.support:design:23.0.0+'

   ##3、单独使用TabLayout的步骤:
         * 先添加Tab,使用tabLayout.newTab()方法创建Tab:
              tabLayout.addTab(tabLayout.newTab().setText("Tab1"));
         * 给tabLayout设置tab改变的监听器 

//2.给tabLayout添加tab改变的监听器
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    public void onTabSelected(TabLayout.Tab tab) {
        Log.e("TAG", "onTabSelected: "+tab.getText());
    }
    public void onTabUnselected(TabLayout.Tab tab) {}
    public void onTabReselected(TabLayout.Tab tab) { }
});

        *在xml中给TabLayout设置属性:

app:tabIndicatorColor="#00f"//横线颜色
app:tabSelectedTextColor="#f00"//选中字体颜色
app:tabTextColor="#0f0"//默认字体颜色
app:tabMode="fixed"//fixed:不能滑动,每个Tab平分宽度,scrollable:可以滑动tab,每个tab宽度很小,适用于tab很多的情景
app:tabGravity="fill"//fill:平分宽度,center:让tab居中,如果tabMode是scrollable,那tabGravity会被忽略

     ##4、和ViewPager关联使用步骤:
          先给ViewPager填充数据,然后关联TabLayout和ViewPager:
            //给ViewPager填充数据
            viewpager.setAdapter(new MyAdapter());
            //关联TabLayout和ViewPager
            tabLayout.setupWithViewPager(viewpager);

4、CoordinatorLayout的使用
     ##1、使用需要依赖design类库:
        compile 'com.android.support:design:23.0.0+'
      ##2、使用它结合AppBarLayout实现向上滑动隐藏ToolBar的效果:
          * AppBarLayout会将包裹的所有子View作为一个整体的AppBar,有着统一的界面着色;
         * 给想滑动出范围的View设置属性,比如ToolBar: 
                app:layout_scrollFlags=”scroll|enterAlways
          * 给发出滑动行为的View设置属性,比如ViewPager:
               pp:layout_behavior="@string/appbar_scrolling_view_behavior"

          *实现步骤
            1.CoordinatorLayout作根控件,包裹AppBarLayout和可滚动的控件,比如ViewPager
            2.AppBarLayout包裹 ToolBar 及TabLayout, ToolBar要滑动,给其设置app:layout_scrollFlags
            3.ViewPager是发出滑动行为的控件,设置属性 app:layout_behavior 注意:带layout_scrollFlags的view需要放在固定View的前面,这样滑动的view才能够正常退出,而固定的view继续留在顶部

5、6.0动态权限管理
6.0之后对权限分了大致3种:普通权限,危险权限,特殊权限。(动态申请权限需要注意的坑
针对危险权限需要做特殊的申请处理,以下图片列举危险权限目录:

申请步骤:
##1、将targetSdkVersion设置为23,注意,如果你将targetSdkVersion设置为>=23,则必须按照Android谷歌的要求,动态的申请权限,如果你暂时不打算支持动态权限申请,则targetSdkVersion最大只能设置为22.
##2、在AndroidManifest.xml中申请你需要的权限,包括普通权限和需要申请的特殊权限
##3、开始申请权限,此处分为3步
       (1)检查是否由此权限checkSelfPermission(),如果已经开启,则直接做你想做的
       (2)如果未开启,则判断是否需要向用户解释为何申请权限shouldShowRequestPermissionRationale。
         3)如果需要(即返回true),则可以弹出对话框提示用户申请权限原因,用户确认后申请权限requestPermissions(),如果不需要(即返回false),则直接申请权限requestPermissions()

 

 7.0 新特性(7.0API


1、应用间共享文件
      在Android7.0系统上。Android 框架强制运行了 StrictMode API 政策禁止向你的应用外公开 file:// URI。
假设一项包含文件 file:// URI类型 的 Intent 离开你的应用,应用失败,并出现 FileUriExposedException 异常,如调用系统相机拍照,或裁切照片。

解决方法:
第一步:在manifest清单文件里注冊provider

        <!-- exported:要求必须为false,为true则会报安全异常。 -->
        <!-- grantUriPermissions:true,表示授予 URI 临时访问权限。 -->
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.huayun.onenotice.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths" />
        </provider>

第二步:指定共享的文件夹
为了指定共享的文件夹我们须要在资源(res)文件夹下创建一个xml文件夹,然后创建一个名为“filepaths”(名字能够随便起,仅仅要和在manifest注冊的provider所引用的resource保持一致就可以)的资源文件。内容例如以下:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <!-- root-path 手机存储根目录 -->
    <!-- external-path:sd ;path:你的应用保存文件的根目录;name随便定义-->
    <external-path path="" name="camera_photos" />
</paths>

第三步:使用FileProvider
上述准备工作做完之后,如今我们就能够使用FileProvider了。
以调用系统相机拍照为例,我们须要将上述拍照代码改动为例如以下:

File file=new File(Environment.getExternalStorageDirectory(), "/temp/"+System.currentTimeMillis() + ".jpg");
if (!file.getParentFile().exists())file.getParentFile().mkdirs();
      Uri imageUri = FileProvider.getUriForFile(context, "com.jph.takephoto.fileprovider", file);//通过FileProvider创建一个content类型的Uri
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //加入这一句表示对目标应用暂时授权该Uri所代表的文件
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//设置Action为拍照
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//将拍取的照片保存到指定URI
startActivityForResult(intent,1000);

2、多窗口支持
    
Android 7.0正式版在近期开始进行了推送,该版本中最大的一个特色就是支持在设备上展示多窗口供用户查看各个应用
多窗口模式有两种:分屏模式和自由形状模式。
      在分屏模式下,手指可以拖动分界线,放大其中一个应用,同时缩小另一个。如果这个应用在新展开的区域绘制滞后,系统将使用 windowBackground 属性或默认 windowBackgroundFallback 样式属性指定的颜色暂时填充该区域。
     进入自由形状模式的操作如下:
(1)打开模拟器或者用usb线连接已root了的设备
(2)在cmd命令行中输入adb shell
(3)然后输入su获得root操作权限
(4)输入settings put global enable_freeform_support 1
(5)重启模拟器或设备。
(6)进入自由形状模式:在overview屏幕下,长按Activity标题,将会在右边出现一个方块状的图标,点击该图标,该Activity该会以自由形状模式展示,通过对该Activity页面的左上角并拖拽,可以修改其形状大小。

多窗口生命周期
(1)多窗口模式不会更改生命周期,多窗口模式下,最近的与用户进行交互的那个Activity为活动状态(Resume),所有其他的Activity虽然可见,但是都会处于暂停状态(pause)。但是这些已暂停但可见的 Activity 在系统中享有比不可见 Activity 更高的优先级。 如果用户与其中一个暂停的 Activity 交互,该 Activity 将恢复,而之前的顶级 Activity 将被暂停。

(2)根据google官方文档上的描述,你如果在应用中做了视频播放效果,那么不要再在onPause中去暂停播放视频了,因为多窗口模式下,你的Activity虽然被暂停,但还是处于可见状态。建议在onStop方法中去暂停播放视频。

(3)切换到多窗口时,Activity会发生配置变更,该变更与系统进行横竖屏切换时的 Activity 生命周期影响基本相同。你可以对 Activity 自行处理配置变更,或着默许系统去销毁 Activity,并以新的尺寸重新创建该 Activity。

3、Project Svelte:后台优化
Project Svelte在持续改善,以最大程度减少生态系统中一系列 Android 设备中系统和应用使用的 RAM。在 Android N 中,Project Svelte 注重优化在后台中运行应用的方式。

后台处理是大多数应用的一个重要部分。处理得当,可实现非常棒的用户体验—即时、快速和情境感知。如果处理不得当,后台处理会毫无必要地消耗 RAM和电池,同时影响其他应用的系统性能。

Android N 删除了三项隐式广播(CONNECTIVITY_ACTION、ACTION_NEW_PICTURE 和ACTION_NEW_VIDEO) 
,以帮助优化内存使用和电量消耗。此项变更很有必要,因为隐式广播会在后台频繁启动已注册侦听这些广播的应用,删除这些广播可以显著提升设备性能和用户体验。

移动设备会经历频繁的连接变更,例如在 Wi-Fi 和移动数据之间切换时。目前,可以通过在应用清单文件中注册一个接收器来侦听隐式 CONNECTIVITY_ACTION广播,让应用能够监控这些变更。由于很多应用会注册接收此广播,因此单次网络切换即会导致所有应用被唤醒并同时处理此广播。同理,应用可以注册接收来自其他应用(例如相机)的隐式ACTION_NEW_PICTURE 和ACTION_NEW_VIDEO 广播。当用户使用相机应用拍摄照片时,这些应用即会被唤醒处理广播。

为减缓这些问题,Android N应用了以下优化措施:

1、面向 Android N 开发的应用不会收到 CONNECTIVITY_ACTION 广播,即使它们已有清单条目来请求接受这些事件的通知。在前台运行的应用如果使用BroadcastReceiver请求接收通知,则仍可以在主线程中侦听CONNECTIVITY_CHANGE。

2、 应用无法发送或接收 ACTION_NEW_PICTURE 和ACTION_NEW_VIDEO广播。此项优化会影响所有应用,而不仅仅是面向 Android N 的应用。

未来的 Android 版本还可能会弃用其他隐式广播以及未绑定的后台服务。有鉴于此,应避免依赖在清单文件中声明的接收器来侦听隐式广播或删除此依赖关系,以及避免或删除对后台服务的依赖关系。

Android 框架提供多种解决方案来降低这些隐式广播或后台服务的必要性。例如,JobScheduler API 提供了一个稳健可靠的机制来安排满足指定条件(例如连入不按流量计费的网络)时所执行的网络操作。甚至可以使用JobScheduler来响应内容提供程序所发生的变更。

 8.0 新特性(8.0API


1、通知渠道---Notifation Channels
通知渠道是由应用自行定义的通知内容类别,借助渠道,开发者可以让用户对不同种类的通知进行精细控制,用户可以单独拦截或更改每个渠道的行为,而不是统一管理应用的所有通知。

创建通知渠道的步骤:

1、创建 NotificationChannel 对象,并设置应用内唯一的通知 ID。

2、配置通知渠道的属性,比如提示声音等。

3、在 NotificationManager 中注册通知渠道对象。



2、画中画模式--PIP

Android O 现已支持 Activity 的画中画模式。PIP 是一种多窗口显示模式,多用于视频播放,即你可以一边发微信一边看视频。

## 关于生命周期
         PIP 模式不会改变 Activity 的生命周期。在指定时间只有最近与用户交互过的 Activity 为活动状态。 该 Activity 将被视为顶级 Activity。 所有其他 Activity 虽然可见,但均处于暂停状态。当一个 Activity 处于 PIP 模式时,其实它是出在暂停状态,但其内容会继续展示。

## API变更
     在 Android O 中新增 PictureInPictureArgs 对象来指明你的 Activity 在 PIP 模式中的属性,比如长宽比等。   
Android O 还新增了以下方法来支持 PIP。
    1、Activity.enterPictureInPictureMode(PictureInPictureArgs args):将Activity置于 PIP 模式之下。
    2、Activity.setPictureInPictureArgs():用于更新 Activity 在 PIP 模式下的设置。如果 Activity 正处于 PIP 模式之下,那么更改的属性将立即生效。

3、自适应图标 — Adaptive Icons
     Android 的屏幕适配一直以来都折磨着不少的开发者。为了帮助开发者更好的与设备 UI 集成,Android O 支持创建自适应图标,系统可以基于设备选择的蒙版将这些图标显示为不同形状。系统还将实现与图标的自动交互,并在启动器、快捷方式、设置、共享对话框以及概览屏幕中使用它们。

## 自适应图标由两张图层和一个形状来定义
    在以前的 Android 版本中,图标大小定义为 48 x 48 dp。现在你必须按照以下的规范定义你的图层大小:
     1、两张图层大小都必须为 108 x 108 dp。
     2、图层中心 72 x 72 dp 范围为可视范围。
     3、系统会保留四周外的 36dp 范围用于生成有趣的视觉效果(如视差和跳动)。

## 创建你的自适应图标
首先你需要在 Application 标签中加入 Android:icon 属性,定义你的 icon 图标。其次如果你需要创建一个原型的 icon,你还需要加入 Android:roundIcon 属性。

接下来,你需要 res/mipmap-anydpi/ic_launcher.xml 文件中定义您的图层。在 选项中加入您的前景和背景图层。


9.0新特性9.0API


1、利用 Wi-Fi RTT 进行室内定位
     Android 9 添加了对 IEEE 802.11mc Wi-Fi 协议(也称为 Wi-Fi Round-Trip-Time (RTT))的平台支持,从而让您的应用可以利用室内定位功能。

在运行 Android 9 且具有硬件支持的设备上,应用可以使用 RTT API 来测量与附近支持 RTT 的 Wi-Fi 接入点 (AP) 的距离。 设备必须已启用位置服务并开启 Wi-Fi 扫描(在 Settings > Location 下),同时您的应用必须有 ACCESS_FINE_LOCATION 权限。

设备无需连接到接入点即可使用 RTT。 为了保护隐私,只有手机可以确定与接入点的距离;接入点无此信息。

如果您的设备测量与 3 个或更多接入点的距离,您可以使用一个多点定位算法来预估与这些测量值最相符的设备位置。 结果通常精准至 1 至 2 米。

通过这种精确性,您可以打造新的体验,例如楼内导航、基于精细位置的服务,如无歧义语音控制(例如,“打开这盏灯”),以及基于位置的信息(如 “此产品是否有特别优惠?”)。

2、显示屏缺口支持

Android 9 支持最新的全面屏,其中包含为摄像头和扬声器预留空间的屏幕缺口。 通过 DisplayCutout 类可确定非功能区域的位置和形状,这些区域不应显示内容。 要确定这些屏幕缺口区域是否存在及其位置,请使用 getDisplayCutout() 函数。

全新的窗口布局属性 layoutInDisplayCutoutMode 让您的应用可以为设备屏幕缺口周围的内容进行布局。 您可以将此属性设为下列值之一:
   LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
   LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
   LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER

可以按以下方法在任何运行 Android 9 的设备或模拟器上模拟屏幕缺口:
  1、启用开发者选项
  2、在 Developer options 屏幕中,向下滚动至 Drawing 部分并选择 Simulate a display with a cutout
  3、选择屏幕缺口的大小。

3、通知
Android 9 引入了多个通知增强功能,可供以 API 级别 28 及以上版本作为目标平台的开发者使用。
 提升短信体验

从 Android 7.0(API 级别 24)开始,您可以添加一个操作以回复短信或直接从通知中输入其他文本。 Android 9 通过下列增强提升了该功能:

简化了针对对话参与者的支持:Person 类可用于识别参与对话的人员,包括他们的头像和 URI。 现在,许多其他 API(如 addMessage())均可利用 [Person] 类而不是 CharSequencePerson 类也支持构建器设计模式。

支持图像:现在,Android 9 可在手机的“短信通知”中显示图像。 您可以使用对短信使用 setData()来显示图像。 以下代码段演示了如何创建 Person 和包含图像的短信。

// Create new Person.
Person sender = new Person()
        .setName(name)
        .setUri(uri)
        .setIcon(null)
        .build();
// Create image message.
Message message = new Message("Picture", time, sender)
        .setData("image/", imageUri);
Notification.MessagingStyle style = new Notification.MessagingStyle(getUser())
        .addMessage("Check this out!", 0, sender)
        .addMessage(message);

(1)将回复另存为草稿:当用户无意中关闭一个短信通知时,您的应用可以检索系统发送的 EXTRA_REMOTE_INPUT_DRAFT。 您可以使用此 extra 预填充应用中的文本字段,以便用户可以完成他们的回复。

(2)确定对话是否为群组对话。您可以使用 setGroupConversation() 以明确确定对话是否为群组对话。

(3)为 Intent 设置语义操作:setSemanticAction() 函数允许您为操作提供语义含义,如“标记为已读”、“删除”和“回复”等。

(4)SmartReply:Android 9 支持在您的短信应用中提供相同的建议回复。 使用 RemoteInput.setChoices() 为用户提供一组标准回复。

4、渠道设置、广播和请勿打扰

Android 8.0 引入了通知渠道,允许您为要显示的每种通知类型创建可由用户自定义的渠道。 Android 9 通过下列变更简化通知渠道设置:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值