Android自定义UI:Paint详解及其在自定义View中的应用

发布时间: 2024-01-21 17:53:07 阅读量: 50 订阅数: 48
目录

1. Android绘图基础

1.1 绘图基础概述

在Android开发中,绘图是一个非常重要的部分,它可以帮助我们实现各种精美的UI效果和动画。绘图基础概述将介绍Android中的绘图基础知识,包括Canvas、Paint等类的基本概念,以及绘制的基本原理和流程。

1.2 绘制原理及流程

Android绘图的原理主要是通过Canvas来完成的。Canvas类提供了丰富的绘制方法,可以绘制各种形状、文本、位图等。在绘制过程中,可以通过Paint类来设置绘制的样式、颜色和效果等属性。绘制流程经常使用在自定义View以及动画效果的实现中。

1.3 Paint类的作用和基本用法

Paint类是Android中用于绘制的工具类,它可以设置颜色、样式、字体、效果等绘制属性。在Paint类中,提供了丰富的方法来设置绘制的属性,比如setColor()、setStyle()、setTextSize()等。在绘制过程中,我们可以通过Paint类来实现各种绘制效果的设置。

2. Paint类详解

2.1 Paint的属性和方法详细解释

在Android中,我们可以使用Paint类来进行绘图操作。Paint类是用于定义绘制图形和文本样式的工具类,它包含了各种属性和方法来设置绘制时的颜色、字体、文本大小等信息。

2.1.1 颜色属性

Paint类中提供了几种设置颜色的方法,可以通过这些方法来设置绘制时的颜色:

  1. Paint paint = new Paint();
  2. paint.setColor(Color.RED); // 设置绘制的颜色为红色
  3. paint.setARGB(255, 255, 0, 0); // 设置绘制的颜色为红色,使用ARGB模式

2.1.2 文本属性

通过Paint类的相关方法,我们可以设置绘制文本时的字体大小、字体样式、字体粗细等属性:

  1. paint.setTextSize(30); // 设置绘制文本的字体大小为30px
  2. paint.setTypeface(Typeface.DEFAULT_BOLD); // 设置绘制文本的字体样式为粗体

2.1.3 绘制样式属性

绘制样式属性包括线条的宽度、线条的样式、绘制的效果等。通过Paint类的相关方法,我们可以设置绘制时的样式属性:

  1. paint.setStrokeWidth(5); // 设置线条的宽度为5px
  2. paint.setStyle(Paint.Style.STROKE); // 设置绘制的样式为只绘制边框
  3. paint.setShader(shader); // 设置绘制的效果为使用渐变效果

2.2 Paint的常见应用场景分析

Paint类作为Android绘图的核心类之一,广泛应用于各种自定义UI的开发中。下面是一些常见应用场景的分析:

2.2.1 绘制基本图形

Paint类可以用于绘制基本图形,比如绘制圆形、矩形、直线等。通过设置Paint的属性,我们可以调整绘制图形时的样式,如颜色、线条粗细等。

2.2.2 绘制文字

通过Paint类的相关方法,我们可以实现绘制文字的功能。可以设置字体的大小、样式,以及字体的颜色等属性。

2.2.3 自定义UI的绘制效果

在自定义UI开发中,我们经常需要实现一些特殊的绘制效果,比如渐变效果、图层效果等。通过设置Paint的属性和使用特定的绘制方法,我们可以实现各种各样的自定义UI效果。

2.3 Paint在自定义UI中的作用及意义

Paint类在自定义UI开发中起着重要的作用,它可以帮助我们实现各种绘制效果,定制化UI界面。通过调整Paint的属性和方法,我们可以实现丰富多样的UI效果,提升用户体验。

在自定义UI的开发中,合理使用Paint类可以让我们更好地掌控UI的外观和效果,将设计师的创意和交互需求完美地呈现在用户面前。

总之,了解并熟练使用Paint类是Android开发中的一项重要技能,它对于自定义UI的开发有着举足轻重的作用。需要深入理解Paint类的属性和方法,以及其在不同场景下的应用,从而更好地进行UI的定制化开发。

3. Android自定义View入门

自定义View是Android开发中非常重要的一部分,通过自定义View可以实现各种炫酷的UI效果,提升用户体验。本章将介绍自定义View的基本概念、实现步骤以及绘图流程。

3.1 自定义View的基本概念

在Android中,View是用户界面的基本构建块,而自定义View则是在现有View的基础上进行扩展和定制,以实现特定的界面效果。自定义View的核心是对onDraw()方法的重写,通过该方法实现自定义的绘图操作。

3.2 自定义View的实现步骤

  • 第一步:创建一个继承自View的子类,例如:
  1. public class CustomView extends View {
  2. // 构造方法
  3. public CustomView(Context context) {
  4. super(context);
  5. init();
  6. }
  7. // 初始化操作
  8. private void init() {
  9. // 进行一些初始化操作,如设置画笔颜色、样式等
  10. }
  11. // 重写onDraw方法,进行自定义绘制操作
  12. @Override
  13. protected void onDraw(Canvas canvas) {
  14. super.onDraw(canvas);
  15. // 在这里进行绘制操作,使用Canvas和Paint进行绘制
  16. }
  17. }
  • 第二步:在onDraw方法中使用Canvas和Paint进行绘制操作,例如:
  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3. super.onDraw(canvas);
  4. Paint paint = new Paint();
  5. paint.setColor(Color.RED);
  6. paint.setStyle(Paint.Style.FILL);
  7. canvas.drawCircle(200, 200, 100, paint);
  8. }

3.3 自定义View中的绘图流程

自定义View的绘图流程主要包括以下几个步骤:

  • 创建自定义View的子类,并重写onDraw方法;
  • 在onDraw方法中使用Canvas和Paint进行绘制操作;
  • 在需要使用自定义View的地方进行引用和添加到布局中。

通过以上步骤,就可以实现一个简单的自定义View,并在应用中使用。接下来,我们将在接下来的章节中深入探讨自定义View的具体应用和细节操作。

4. Android自定义UI的实际应用

在本章中,我们将深入探讨如何利用Android中的Paint类来实现自定义UI,并分析其常见应用场景。通过学习本章内容,读者将能够掌握如何使用Paint来绘制基本图形、实现文字绘制和样式设置,以及运用Paint的高级功能来实现渐变效果和图层处理。

4.1 在自定义View中使用Paint绘制基本图形

在Android中,我们可以通过自定义View来实现自己想要的UI效果。下面是一个简单的示例,演示了如何在自定义View中使用Paint来绘制基本图形:

  1. public class CustomShapeView extends View {
  2. private Paint mPaint;
  3. public CustomShapeView(Context context) {
  4. super(context);
  5. init();
  6. }
  7. public CustomShapeView(Context context, AttributeSet attrs) {
  8. super(context, attrs);
  9. init();
  10. }
  11. public CustomShapeView(Context context, AttributeSet attrs, int defStyle) {
  12. super(context, attrs, defStyle);
  13. init();
  14. }
  15. private void init() {
  16. mPaint = new Paint();
  17. mPaint.setColor(Color.BLUE); // 设置颜色为蓝色
  18. mPaint.setStyle(Paint.Style.FILL); // 设置为填充模式
  19. mPaint.setAntiAlias(true); // 开启抗锯齿
  20. }
  21. @Override
  22. protected void onDraw(Canvas canvas) {
  23. super.onDraw(canvas);
  24. // 绘制矩形
  25. canvas.drawRect(100, 100, 300, 300, mPaint);
  26. // 绘制圆形
  27. canvas.drawCircle(500, 200, 100, mPaint);
  28. }
  29. }

在上述代码中,我们创建了一个CustomShapeView继承自View,并在其onDraw方法中使用Paint来绘制矩形和圆形。通过设置Paint的颜色、样式和抗锯齿等属性,我们可以实现不同的绘制效果。

4.2 利用Paint实现文字绘制和样式设置

除了绘制基本图形外,Paint还可以用于文字的绘制和样式设置。以下是一个示例,演示了如何在自定义View中使用Paint来绘制文字并设置其样式:

  1. public class CustomDrawTextView extends View {
  2. private Paint mPaint;
  3. private String mText = "Hello, Custom View!";
  4. public CustomDrawTextView(Context context) {
  5. super(context);
  6. init();
  7. }
  8. public CustomDrawTextView(Context context, AttributeSet attrs) {
  9. super(context, attrs);
  10. init();
  11. }
  12. public CustomDrawTextView(Context context, AttributeSet attrs, int defStyle) {
  13. super(context, attrs, defStyle);
  14. init();
  15. }
  16. private void init() {
  17. mPaint = new Paint();
  18. mPaint.setColor(Color.BLACK);
  19. mPaint.setTextSize(60);
  20. }
  21. @Override
  22. protected void onDraw(Canvas canvas) {
  23. super.onDraw(canvas);
  24. canvas.drawText(mText, 100, 100, mPaint);
  25. }
  26. }

在上述代码中,我们创建了一个CustomDrawTextView继承自View,并在其onDraw方法中使用Paint来绘制指定文字。通过设置Paint的颜色、文字大小等属性,我们可以实现不同样式的文字绘制效果。

4.3 Paint的高级应用:渐变效果和图层处理

在实际应用中,我们常常需要实现一些特殊的绘制效果,如渐变色背景和图层叠加。下面是一个示例,演示了如何在自定义View中使用Paint来实现渐变效果和图层处理:

  1. public class CustomGradientView extends View {
  2. private Paint mPaint;
  3. public CustomGradientView(Context context) {
  4. super(context);
  5. init();
  6. }
  7. public CustomGradientView(Context context, AttributeSet attrs) {
  8. super(context, attrs);
  9. init();
  10. }
  11. public CustomGradientView(Context context, AttributeSet attrs, int defStyle) {
  12. super(context, attrs, defStyle);
  13. init();
  14. }
  15. private void init() {
  16. mPaint = new Paint();
  17. // 创建线性渐变
  18. Shader shader = new LinearGradient(0, 0, 500, 500, Color.RED, Color.BLUE, Shader.TileMode.CLAMP);
  19. mPaint.setShader(shader);
  20. }
  21. @Override
  22. protected void onDraw(Canvas canvas) {
  23. super.onDraw(canvas);
  24. // 绘制矩形
  25. canvas.drawRect(0, 0, 500, 500, mPaint);
  26. }
  27. }

在上述代码中,我们创建了一个CustomGradientView继承自View,并在其onDraw方法中使用Paint来绘制带有渐变效果的矩形。通过设置Paint的Shader,我们可以实现渐变效果的绘制。同时,利用图层的叠加,我们可以实现更加丰富的视觉效果。

通过以上示例,我们可以看到在Android中利用Paint类可以实现丰富多彩的自定义UI效果,为用户提供更加丰富多样的视觉体验。

以上是第四章的内容介绍,下一步,我们将进入第五章,实例分析:创建一个自定义UI。

5. 实例分析:创建一个自定义UI

5.1 搭建自定义View的框架

在开始创建自定义UI之前,我们首先需要搭建一个自定义View的框架。具体步骤如下:

  1. 创建一个新的Java类文件,命名为CustomView,继承自View类。
  2. 在CustomView类中重写构造方法,以便在代码中实例化CustomView时使用。
    1. public CustomView(Context context) {
    2. super(context);
    3. }
    4. public CustomView(Context context, @Nullable AttributeSet attrs) {
    5. super(context, attrs);
    6. }
    7. public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    8. super(context, attrs, defStyleAttr);
    9. }
  3. 在CustomView类中重写onDraw方法,用于进行绘制操作。
    1. @Override
    2. protected void onDraw(Canvas canvas) {
    3. super.onDraw(canvas);
    4. // 在这里进行绘制操作
    5. }
  4. 在这里可以使用Paint类的各种方法进行绘制,如绘制基本图形、绘制文字等。

5.2 使用Paint绘制不规则图形

现在我们将使用Paint类在自定义UI中绘制一个不规则图形。具体步骤如下:

  1. 在onDraw方法中创建一个Path对象,并通过该对象定义不规则图形的路径。
    1. Path path = new Path();
    2. path.moveTo(100, 100);
    3. path.lineTo(200, 100);
    4. path.lineTo(150, 200);
    5. path.close();
  2. 创建一个Paint对象,并设置其颜色和样式。
    1. Paint paint = new Paint();
    2. paint.setColor(Color.RED);
    3. paint.setStyle(Paint.Style.FILL);
  3. 在onDraw方法中使用canvas的drawPath方法将路径绘制出来。
    1. canvas.drawPath(path, paint);

5.3 添加触摸事件交互效果

我们可以通过为自定义View添加触摸事件,实现交互效果。具体步骤如下:

  1. 在CustomView类中重写onTouchEvent方法,处理触摸事件。
    1. @Override
    2. public boolean onTouchEvent(MotionEvent event) {
    3. // 获取触摸点的坐标
    4. float x = event.getX();
    5. float y = event.getY();
    6. switch (event.getAction()) {
    7. case MotionEvent.ACTION_DOWN:
    8. // 当按下时,判断触摸点是否在不规则图形的区域内
    9. if (path.contains(x, y)) {
    10. // 在区域内,执行相应操作
    11. }
    12. break;
    13. case MotionEvent.ACTION_MOVE:
    14. // 当移动时,执行相应操作
    15. break;
    16. case MotionEvent.ACTION_UP:
    17. // 当抬起时,执行相应操作
    18. break;
    19. }
    20. return true;
    21. }
  2. 根据具体需求,在ACTION_DOWN、ACTION_MOVE、ACTION_UP等不同情况下,对自定义UI进行相应的操作。

以上是通过使用Paint类在自定义UI中绘制不规则图形并添加触摸事件交互效果的实例分析。

下一篇文章中,我们将进一步探讨绘制性能优化方法和Paint在自定义UI中的注意事项。敬请期待!

代码总结:

这一章节我们学习了如何搭建自定义View的框架,以及利用Paint绘制不规则图形和添加触摸事件交互效果的实现方法。

结果说明:

通过以上实例的学习,我们可以灵活运用自定义View和Paint类实现各种个性化的UI效果,提升用户体验和界面交互性。下一章节将进一步讨论性能优化和注意事项,帮助读者更好地应用自定义UI。

6. 优化与总结

6.1 绘制性能优化方法

在进行Android自定义UI的绘制过程中,为了提高绘制性能和效率,我们可以采取一些优化方法,例如:

  • 减少不必要的绘制操作:避免在每一帧都进行重复绘制,只在需要更新时进行绘制。可以利用invalidate()方法手动触发重绘,并使用onDraw()方法进行绘制操作。
  • 利用硬件加速:Android提供了硬件加速功能,可以通过在<application>标签下的manifest文件中添加android:hardwareAccelerated="true"来开启硬件加速。硬件加速可以利用GPU进行绘图,加快绘制速度。
  • 使用缓存和复用:对于一些频繁绘制的视图元素,可以将其绘制结果进行缓存,以便重复使用。可以使用Canvassave()restore()方法来保存和恢复绘制状态。

6.2 Paint在自定义UI中的注意事项

在使用Paint进行自定义UI绘制时,需要注意以下事项:

  • 尽量复用Paint对象:创建和销毁Paint对象是比较耗费性能的操作,所以在绘制过程中尽量复用已有的Paint对象。
  • 避免过多的绘制操作:过多的绘制操作会影响性能,可以通过合并绘制操作,或者利用缓存机制来减少绘制次数。
  • 谨慎使用抗锯齿和阴影效果:抗锯齿和阴影效果会增加绘制的复杂度和计算量,需要谨慎使用,避免影响绘制的性能。

6.3 总结与展望:Android自定义UI的发展趋势

自定义UI是Android开发中非常重要的一部分,它能够有效地提升应用的用户体验和差异化竞争力。随着Android技术的不断发展,自定义UI也在不断演进和改进。

未来,我们可以看到以下几个方向的发展趋势:

  • 更加丰富多样的绘制效果:随着硬件性能的提升和绘图技术的改进,我们可以实现更加丰富多样的绘制效果,例如3D效果、粒子效果等,提供更加炫酷的用户界面。
  • 更加智能化的自定义UI:随着人工智能和机器学习的发展,我们可以利用智能算法对用户的行为进行分析和预测,进而自动生成和调整UI界面,提供更加个性化和智能化的用户体验。
  • 更加简化的自定义UI开发工具和框架:为了降低自定义UI开发的门槛,未来可能会出现更加简化和易用的开发工具和框架,使开发者能够更快速地实现自定义UI功能。

总的来说,Android自定义UI的发展趋势是越来越多样化、智能化和简化化。通过不断学习和探索,我们可以将自定义UI发挥到极致,提供更好的用户体验和价值。

corwn 最低0.47元/天 解锁专栏
买1年送3月
点击查看下一篇
profit 百万级 高质量VIP文章无限畅学
profit 千万级 优质资源任意下载
profit C知道 免费提问 ( 生成式Al产品 )

相关推荐

陆鲁

资深技术专家
超过10年工作经验的资深技术专家,曾在多家知名大型互联网公司担任重要职位。任职期间,参与并主导了多个重要的移动应用项目。
专栏简介
《Android自定义UI开发》专栏深入剖析了Android平台上自定义UI的开发技术与实践,旨在帮助开发者掌握Android自定义UI的核心知识与技能。从基础概念与常用工具介绍开始,逐步深入探讨Canvas绘图、Paint详解、Path路径绘制、图形变换等高级绘制操作,涵盖了饼图、柱状图、图像处理、滤镜效果等实际应用场景。此外,还探讨了自定义控件的布局与事件处理、绘制动画与属性动画的运用、手势识别与触摸事件处理等关键技术,同时介绍了性能优化、自定义主题与样式、创意设计与用户体验优化等实用技巧。此外,还深入介绍了矢量图形绘制与应用、3D图形与OpenGL ES的实现方法,为开发者提供了全方位的自定义UI开发知识体系。
最低0.47元/天 解锁专栏
买1年送3月
百万级 高质量VIP文章无限畅学
千万级 优质资源任意下载
C知道 免费提问 ( 生成式Al产品 )

最新推荐

DVE故障排查入门:快速定位问题点:故障诊断快速入门指南

![DVE故障排查入门:快速定位问题点:故障诊断快速入门指南](https://img-blog.csdnimg.cn/20201014132557235.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3ZpcnR1YWxpemF0aW9uXw==,size_16,color_FFFFFF,t_70) # 摘要 DVE故障排查是一门旨在快速定位并解决网络、系统及应用程序问题的技术,对于维护系统稳定性和性能至关重要。本文首先概述了DVE

【曲面建模技巧】:SolidWorks解决复杂形状设计【难题】

![【曲面建模技巧】:SolidWorks解决复杂形状设计【难题】](https://www.javelin-tech.com/blog/wp-content/uploads/2015/09/convert-entities-loops-converted.png) # 摘要 本文探讨了曲面建模在产品设计领域的关键作用及其在实际应用中的技巧提升。从SolidWorks曲面建模基础入手,详细介绍了用户界面、专用工具及基本曲面创建方法,强调了曲面编辑与修改技术的重要性。随后深入分析了高级技巧与应用,包含复杂曲面建模实例、曲线运用,以及使用曲面分析工具进行质量控制。文章还讨论了SolidWorks

Chrome浏览器v101.0.4951.54多平台同步优化:一文掌握同步功能与技巧

![Chrome浏览器v101.0.4951.54多平台同步优化:一文掌握同步功能与技巧](https://d1muf25xaso8hp.cloudfront.net/https%3A%2F%2Ff2be1865ee7383cbb497ad64c22d3900.cdn.bubble.io%2Ff1650268123753x675672033214540000%2F38_2.png?w=1024&h=567&auto=compress&dpr=1&fit=max) # 摘要 本文详细探讨了Chrome浏览器v101.0.4951.54版本的多平台同步机制、扩展程序同步技巧、标签页与书签同步方法

【LoRa设备选型与配置指南】:从零开始的物联网构建

![【LoRa设备选型与配置指南】:从零开始的物联网构建](https://deepbluembedded.com/wp-content/uploads/2023/03/ESP32-Power-Modes-Light-Sleep-Power-Consumption-1024x576.png?ezimgfmt=rs:362x204/rscb6/ngcb6/notWebP) # 摘要 本文全面概述了LoRa技术的基础知识,并深入探讨了其在物联网中的应用。首先,我们分析了LoRa设备的选型原则与方法,包括技术参数分析、设备分类、应用场景及选型工具。随后,文章聚焦于LoRa设备的配置与网络部署,着重

【风险管理新策略】:Copula理论在MATLAB中的应用详解

![【风险管理新策略】:Copula理论在MATLAB中的应用详解](https://opengraph.githubassets.com/17b7b0fdeef2d3735b4334c5ce0800be99c636c3d09a085abe49c410a39a967b/stochasticresearch/copula) # 摘要 风险管理是企业运营和金融决策中的核心环节,而Copula理论为风险管理提供了强大的数学工具,尤其在度量和分析多变量风险相关性方面。本文首先介绍了风险管理与Copula理论的基本概念,然后深入探讨了MATLAB软件在Copula函数构建和分析中的应用。通过具体的案例

【数据库性能提升秘籍】:12306架构优化实战指南

![【数据库性能提升秘籍】:12306架构优化实战指南](https://media.geeksforgeeks.org/wp-content/uploads/20230831152524/vertical-sharding.png) # 摘要 随着12306在线购票系统的使用量激增,其数据库性能优化成为保证系统稳定运行的关键。本文首先概述了数据库性能优化的重要性,并深入探讨了12306系统架构所面临的挑战。分析了其架构中关键的优化点,包括读写分离、缓存机制以及分布式数据库的选择与应用。进一步地,本文通过实践技术,如SQL查询优化、数据库配置优化和分布式数据库应用,来实现性能提升。通过123

内网Kubernetes集群优化:性能提升的实战案例分析(专家级攻略)

![内网Kubernetes集群优化:性能提升的实战案例分析(专家级攻略)](https://www.atatus.com/blog/content/images/2023/09/requests-and-limits.png) # 摘要 随着容器化技术的快速发展,Kubernetes已成为管理容器集群的行业标准。本文系统性地探讨了Kubernetes集群优化的各个方面,从基础架构性能指标的监控到网络、存储配置的优化,再到资源管理和安全加固的最佳实践。通过深入分析Kubernetes的核心组件、性能监控指标、故障排查技术以及资源调度策略,本文提出了一系列针对性的优化方法。文章还通过具体案例分

【故障诊断与解决】:萤石CS-W1-FE300F(EM)问题快速定位与解决方案(故障处理必备)

![萤石CS-W1-FE300F](http://www.cqhrkj.com.cn/upload/photo/3551492843661.png) # 摘要 本文针对萤石CS-W1-FE300F(EM)产品的问题快速定位与解决进行综合分析。首先介绍了故障诊断的理论框架和基本步骤,然后对硬件、软件及网络故障进行分类与分析。在实践章节中,详细探讨了接入、视频、系统等常见问题的处理解决方案。进阶章节深入讨论了网络环境、性能瓶颈和安全性故障的高级排查技术。文章最后强调了日常维护的最佳实践和预防性维护策略,并分享了真实故障案例,总结了故障解决和维护升级的经验。本研究旨在为技术人员提供全面的故障排查与

【网络性能革命】:TDD-LTE切换过程与优化技术揭秘

![【网络性能革命】:TDD-LTE切换过程与优化技术揭秘](https://i1.wp.com/www.techtrained.com/wp-content/uploads/2017/10/LTE_Uplink_THrougghput_LTE_Adcanced.jpg?resize=1180%2C312) # 摘要 TDD-LTE技术作为一种高效能的移动通信标准,其网络切换原理及性能对用户体验至关重要。本文详细探讨了TDD-LTE网络的切换原理,包括切换过程中的触发条件、决策过程以及关键技术细节,如X2和S1接口的作用和相关信令流程。在此基础上,本文进一步分析了切换性能指标,如切换成功率和

【10大技巧揭秘】:如何利用ES7243芯片显著提升ADC语音清晰度

![【10大技巧揭秘】:如何利用ES7243芯片显著提升ADC语音清晰度](https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/1023/filter.jpg) # 摘要 本文首先介绍了ES7243芯片的基本信息和模数转换器(ADC)的基础知识。随后,深入探讨了ES7243芯片在ADC应用中的工作原理、特性分析、数字信号处理以及提升语音清晰度的理论基础。文章进一步提供了ES7243芯片的优化设置技巧,包括硬件连接配置、软件编程和实时调整策略。通过对ES7243芯片的实践应用案例进行分析,
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部