qidao123.com技术社区-IT企服评测·应用市场

标题: Android View设置圆角方式大全 [打印本页]

作者: 反转基因福娃    时间: 2025-5-9 06:28
标题: Android View设置圆角方式大全
一、弁言

在 Android 开发中,圆角筹划是提升界面美观度和用户体验的重要手段。从简朴的按钮到复杂的布局容器,圆角可以让界面元素显得更加柔和、现代。本文将全面梳理 Android View 设置圆角的全部方式,涵盖 XML 设置、代码动态实现、自定义绘制、第三方库等多个维度,并联合源码深入分析其原理,同时给出性能优化的最佳实践。
二、XML 布局文件设置圆角

2.1 使用 ShapeDrawable

  1. <shape xmlns:android="http://schemas.android.com/apk/res/android"
  2.     android:shape="rectangle">
  3.     <!-- 圆角半径,这里统一设置四个角的圆角半径为 16dp -->
  4.     <corners android:radius="16dp"/>
  5.     <!-- 设置填充颜色为粉色 -->
  6.     <solid android:color="#FF4081"/>
  7.     <!-- 设置边框,宽度为 2dp,颜色为黄色 -->
  8.     <stroke
  9.         android:width="2dp"
  10.         android:color="#FFEB3B"/>
  11.     <!-- 设置内边距,上下为 8dp,左右为 16dp -->
  12.     <padding
  13.         android:top="8dp"
  14.         android:bottom="8dp"
  15.         android:left="16dp"
  16.         android:right="16dp"/>
  17. </shape>
复制代码
原理分析


2.2 使用 GradientDrawable

  1. <gradient
  2.     xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:type="linear"
  4.     <!-- 设置渐变的起始颜色为粉色 -->
  5.     android:startColor="#FF4081"
  6.     <!-- 设置渐变的结束颜色为蓝色 -->
  7.     android:endColor="#2196F3"
  8.     <!-- 设置渐变的角度为 45 度 -->
  9.     android:angle="45">
  10.     <!-- 设置圆角半径为 24dp -->
  11.     <corners android:radius="24dp"/>
  12. </gradient>
复制代码
原理分析


2.3 使用 LayerDrawable

  1. <layer-list
  2.     xmlns:android="http://schemas.android.com/apk/res/android">
  3.     <!-- 第一个图层 -->
  4.     <item>
  5.         <shape android:shape="rectangle">
  6.             <!-- 设置圆角半径为 20dp -->
  7.             <corners android:radius="20dp"/>
  8.             <!-- 设置填充颜色为白色 -->
  9.             <solid android:color="#FFFFFF"/>
  10.         </shape>
  11.     </item>
  12.     <!-- 第二个图层,相对于第一个图层向下和向右偏移 2dp -->
  13.     <item android:bottom="2dp" android:right="2dp">
  14.         <shape android:shape="rectangle">
  15.             <!-- 设置圆角半径为 20dp -->
  16.             <corners android:radius="20dp"/>
  17.             <!-- 设置填充颜色为浅灰色 -->
  18.             <solid android:color="#EEEEEE"/>
  19.         </shape>
  20.     </item>
  21. </layer-list>
复制代码
原理分析


三、代码动态设置圆角

3.1 使用 View.setBackground ()

  1. // 创建一个 GradientDrawable 对象
  2. val drawable = GradientDrawable()
  3. // 设置圆角半径为 24f
  4. drawable.cornerRadius = 24f
  5. // 设置填充颜色为资源文件中定义的 colorPrimary 颜色
  6. drawable.setColor(ContextCompat.getColor(this, R.color.colorPrimary))
  7. // 将 GradientDrawable 对象设置为 View 的背景
  8. view.setBackground(drawable)
复制代码
原理分析


3.2 使用 ViewOutlineProvider

  1. // 为 View 设置自定义的 OutlineProvider
  2. view.outlineProvider = object : ViewOutlineProvider() {
  3.     override fun getOutline(view: View, outline: Outline) {
  4.         // 设置 Outline 为一个圆角矩形,圆角半径为 24f
  5.         outline.setRoundRect(0, 0, view.width, view.height, 24f)
  6.     }
  7. }
  8. // 开启 View 的裁剪功能,使其按照 Outline 进行裁剪
  9. view.clipToOutline = true
复制代码
原理分析


3.3 使用 Path 裁剪

  1. override fun onDraw(canvas: Canvas) {
  2.     // 创建一个 Path 对象
  3.     val path = Path()
  4.     // 向 Path 中添加一个圆角矩形,圆角半径为 24f
  5.     path.addRoundRect(0f, 0f, width.toFloat(), height.toFloat(), 24f, 24f, Path.Direction.CW)
  6.     // 使用 Path 对 Canvas 进行裁剪
  7.     canvas.clipPath(path)
  8.     // 调用父类的 onDraw 方法进行绘制
  9.     super.onDraw(canvas)
  10. }
复制代码
原理分析


四、第三方库实现圆角

4.1 AndroidX CardView

  1. <com.google.android.material.card.MaterialCardView
  2.     android:layout_width="match_parent"
  3.     android:layout_height="wrap_content"
  4.     <!-- 设置卡片的圆角半径为 20dp -->
  5.     app:cardCornerRadius="20dp"
  6.     <!-- 设置卡片的阴影高度为 8dp -->
  7.     app:cardElevation="8dp">
  8.     <!-- 子视图 -->
  9. </com.google.android.material.card.MaterialCardView>
复制代码
原理分析


4.2 RoundedImageView

  1. <com.makeramen.roundedimageview.RoundedImageView
  2.     android:layout_width="200dp"
  3.     android:layout_height="200dp"
  4.     <!-- 设置圆角半径为 40dp -->
  5.     app:riv_corner_radius="40dp"
  6.     <!-- 设置边框宽度为 2dp -->
  7.     app:riv_border_width="2dp"
  8.     <!-- 设置边框颜色为黄色 -->
  9.     app:riv_border_color="#FFEB3B"
  10.     <!-- 设置是否对背景进行变形处理 -->
  11.     app:riv_mutate_background="true"
  12.     <!-- 设置图片资源 -->
  13.     android:src="@drawable/avatar"/>
复制代码
原理分析


4.3 Material Design Components

  1. <com.google.android.material.button.MaterialButton
  2.     android:layout_width="wrap_content"
  3.     android:layout_height="wrap_content"
  4.     android:text="Button"
  5.     <!-- 设置按钮的圆角半径为 16dp -->
  6.     app:cornerRadius="16dp"
  7.     <!-- 设置按钮的边框宽度为 2dp -->
  8.     app:strokeWidth="2dp"
  9.     <!-- 设置按钮的边框颜色为资源文件中定义的 colorAccent 颜色 -->
  10.     app:strokeColor="@color/colorAccent"/>
复制代码
原理分析


五、高级技巧与优化

5.1 动态圆角动画

  1. // 从资源文件中加载一个过渡动画
  2. val transition = TransitionInflater.from(this).inflateTransition(R.transition.change_bounds)
  3. // 获取场景根视图
  4. val sceneRoot = findViewById<ViewGroup>(R.id.scene_root)
  5. // 开始延迟过渡动画
  6. TransitionManager.beginDelayedTransition(sceneRoot, transition)
  7. // 动画触发
  8. view.animate().withEndAction {
  9.     // 创建一个 GradientDrawable 对象
  10.     val drawable = GradientDrawable()
  11.     // 根据当前圆角半径的值,切换圆角半径
  12.     drawable.cornerRadius = if (currentRadius == 0f) 24f else 0f
  13.     // 更新当前圆角半径的值
  14.     currentRadius = drawable.cornerRadius
  15.     // 将 GradientDrawable 对象设置为 View 的背景
  16.     view.setBackground(drawable)
  17. }.start()
复制代码
原理分析


5.2 硬件加快优化

  1. <application
  2.     android:hardwareAccelerated="true"
  3.     ...>
  4. </application>
复制代码
原理分析


5.3 内存优化

  1. // 复用 Drawable,创建一个共享的 GradientDrawable 对象
  2. val sharedDrawable = GradientDrawable()
  3. // 将共享的 GradientDrawable 对象设置为 view1 的背景
  4. view1.setBackground(sharedDrawable)
  5. // 将共享的 GradientDrawable 对象设置为 view2 的背景
  6. view2.setBackground(sharedDrawable)
  7. // 及时回收资源,在 View 从窗口中分离时调用
  8. override fun onDetachedFromWindow() {
  9.     super.onDetachedFromWindow()
  10.     // 对背景 Drawable 进行变异处理,避免共享状态的影响
  11.     (view.background as? GradientDrawable)?.mutate()
  12.     // 将 View 的背景设置为 null,释放资源
  13.     view.setBackground(null)
  14. }
复制代码
原理分析


六、源码深度分析

6.1 View 圆角实现原理

  1. // View.java
  2. public void setOutlineProvider(OutlineProvider outlineProvider) {
  3.     // 如果当前已经设置了 OutlineProvider,则调用其 onStop 方法
  4.     if (mOutlineProvider != null) {
  5.         mOutlineProvider.onStop(this);
  6.     }
  7.     // 更新 OutlineProvider
  8.     mOutlineProvider = outlineProvider;
  9.     // 如果新设置的 OutlineProvider 不为 null,则调用其 onStart 方法
  10.     if (mOutlineProvider != null) {
  11.         mOutlineProvider.onStart(this);
  12.     }
  13.     // 使 Outline 无效,触发重新计算
  14.     invalidateOutline();
  15.     // 使 View 无效,触发重绘
  16.     invalidate();
  17. }
  18. // OutlineProvider.java
  19. public abstract class OutlineProvider {
  20.     public void getOutline(View view, Outline outline) {
  21.         // 默认设置 Outline 为一个椭圆形
  22.         outline.setOval(0, 0, view.getWidth(), view.getHeight());
  23.     }
  24. }
复制代码
原理分析


6.2 硬件加快渲染流程

  1. // RenderNode.java
  2. public void setRoundRect(int left, int top, int right, int bottom, float radius) {
  3.     // 调用底层的绘制节点设置圆角矩形
  4.     mDrawNode.setRoundRect(left, top, right, bottom, radius);
  5.     // 标记属性无效,需要重新计算
  6.     mInvalidateProperties = true;
  7. }
  8. // RenderProxy.java
  9. public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry) {
  10.     // 调用底层的本地方法绘制圆角矩形
  11.     nDrawRoundRect(mNativeRenderProxy, left, top, right, bottom, rx, ry);
  12. }
复制代码
原理分析


七、常见问题与办理方案

7.1 圆角不表现


  1. view.post {
  2.     // 在 View 布局完成后,设置背景资源
  3.     view.setBackgroundResource(R.drawable.rounded_bg)
  4. }
复制代码
原理分析


7.2 边沿锯齿


  1. // 开启 Drawable 的抗锯齿功能
  2. drawable.isAntiAlias = true
  3. // 使用抗锯齿的画笔绘制圆角矩形
  4. canvas.drawRoundRect(rect, radius, radius, paint)
复制代码
原理分析


7.3 性能问题


八、不同场景下的实现策略

场景推荐方案优势简朴圆角矩形ShapeDrawable / GradientDrawable代码简洁,兼容性好,实用于大多数简朴的圆角矩形需求。可以通过 XML 或代码动态设置,易于维护。复杂形状Path 裁剪灵活性高,支持任意形状的圆角裁剪。可以通过 Path 类定义复杂的路径,实现独特的形状效果。需要阴影效果CardView内置阴影支持,性能优化。CardView 是 AndroidX Material Design 库中的组件,提供了简朴的属性来设置圆角和阴影,同时对性能进行了优化。图片圆角RoundedImageView专业处理图片,支持多种效果。RoundedImageView 是一个开源的第三方库,专门用于处理图片的圆角效果,支持圆形、圆角、椭圆等多种形状,还可以设置边框和配景变形效果。动态圆角动画ViewOutlineProvider + 动画流通过渡,硬件加快优化。通过 ViewOutlineProvider 实现圆角效果,联合 ViewPropertyAnimator 或 TransitionManager 实现动态圆角动画,使用硬件加快机制,过渡效果流通。 九、性能对比测试

方法内存占用(KB)渲染时间(ms)兼容性ShapeDrawable1.20.8API 1+CardView3.51.5API 21+OutlineProvider2.11.2API 21+自定义 Path 绘制4.82.5API 1+RoundedImageView5.21.8API 1+ 性能分析



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/) Powered by Discuz! X3.4