HarmonyOS 鸿蒙Next 使用clipShape进行裁剪后,borderRadius无法生效怎么处理

【问题现象】

对容器组件使用clipShape进行裁剪后,再使用borderRadius对被裁剪容器设置圆角时无法生效,如下图所示效果:

点击放大

【背景知识】

1. 设置组件圆角的方法

1.1 borderRadius

borderRadius属性用于设置组件边框的圆角,可以同时设置四个角,也可以分别对四个角的圆角大小进行设置。为了避免因子组件尺寸大于组件,导致子组件覆盖圆角,可以搭配属性clip使用。

1.2 clipShape

clipShape属性用于对组件进行形状裁剪,通过传入不同的组件类型,将组件裁剪为对应的形状。

2. 绘制圆角的方法

2.1 Path

  • Path是路径绘制组件,可以通过commands属性绘制出需求的形状,包括圆角(圆角多边形)。
  • 关于贝塞尔曲线和控制点的关系:由一组控制点的向量决定,给定的控制点按顺序连接构成控制多边形。

2.2 Path和clipShape的区别

  • Path是绘制组件,通过设置路径绘制出需求的形状,其填充区域一般是颜色而非图片。
  • clipShape是通用属性,通过设置不同组件类型对组件进行裁剪,裁剪后的形状背景是组件的一部分。比如对Image组件进行裁剪,裁剪后的形状背景是该Image组件图片的一部分。

【定位思路】

borderRadius属性从规格上是相对于组件的大小而言的,当组件同时设置borderRadius和clipShape时,borderRadius会首先生效,对整个组件设置圆角效果,然后clipShape裁剪效果会覆盖borderRadius的圆角效果,导致borderRadius不生效。

【解决方案】

1. 对裁剪的组件设置圆角

使用clipShape对组件进行裁剪时,根据需求,对需设置为圆角的角进行圆角裁剪处理。被裁剪的组件可以是容器组件(如Column、Row等)或Image组件。

注意:不能设置两次clipShape属性进行多次裁剪,否则最后一个clipShape的裁剪将会覆盖前面的clipShape裁剪。

以下示例对Image组件设置clipShape属性,使用PathShape形状描述组件被裁剪后的形状。

代码示例如下:

 @Entry
 @Component

 struct ClipFilletCorner {
   // 定义PathShape绘制的路线
   /*
     绘制原始图形,即不裁剪,绘制路线的单位为px,宽高默认单位为vp,可以按需要使用像素单位转换方法进行转换
    */
   commands1:string=`M0 0 L${vp2px(300)} 0 L${vp2px(300)}${vp2px(200)} L0 ${vp2px(200)} Z`
   /*
     将图片裁剪为三角形
     * commands的命令M是定义绘制的起点,如M0 0是定义点(0, 0)为绘制起点
     * commands的命令L是绘制当前点到指定点的直线,如L600 0是绘制当前点到(600, 0)的直线
     * commands的命令Z是指绘制当前点到起点的直线并结束绘制
    */
   commands2:string='M0 0 L600 0 L600 300 Z'
   /*
     将图片裁剪为带圆角的不规则图形
     * commands的命令H是绘制当前点到对应x坐标的点的水平线,如M0 100 H300是绘制从(0, 100)到(300, 100)的水平线
     * commands的命令V是绘制当前点到对应y坐标的点的垂直线,如M100 0 V300是绘制从(100, 0)到(100, 300)的垂直线
     * commands的命令S是绘制当前点到终点的二次贝塞尔曲线,前两个值是设置控制点,后两个值是曲线终点
    */
   commands3:string='M0 100 S0 0 100 0 H300 S400 0 400 100 V300 S400 400 300 400 H200Z'
   @State shapeNum:number=1

   build() {
     Column() {
       // 待裁剪图片
       Image($r('app.media.startIcon'))
         .height(200)
         .width(300)
         .margin({top:10, bottom:10})
         .objectFit(ImageFit.Cover)
         .borderRadius({topRight:5})
         .clipShape(newPathShape().commands(this.shapeNum===1?this.commands1:this.shapeNum===2?this.commands2:this.commands3))

       // 定义命令控制器
       Row() {
         Button('Original')
           .type(ButtonType.Capsule)
           .width(80)
           .onClick(() => {
             this.shapeNum=1
           })

         Button('Triangle')
           .type(ButtonType.Capsule)
           .width(80)
           .onClick(() => {
             this.shapeNum=2
           })

         Button('Irregular')
           .type(ButtonType.Capsule)
           .width(80)
           .onClick(() => {
             this.shapeNum=3
           })
       }.width(300)
       .height(100)
       .justifyContent(FlexAlign.SpaceEvenly)
     }.width('100%')
     .height('40%')
     .backgroundColor(Color.Orange)
     .justifyContent(FlexAlign.Center)
     .alignItems(HorizontalAlign.Center)
   }
 }

效果图:

点击放大

2. 绘制带圆角的组件

某些场景下可能需要绘制出带有圆角或其他形状的图形,此时可以使用Path组件进行绘制。

代码示例如下:

@Entry
@Component
struct PathFilletCorner {
  build() {
    Row() {
      // 绘制上一示例的带圆角的不规则图形
      Path()
        .fill(Color.Pink)
        .stroke(Color.Blue)
        // 命令与上一示例的commands3相同
        .commands('M0 100 S0 0 100 0 H300 S400 0 400 100 V300 S400 400 300 400 H200Z')

      // 绘制带圆角的三角形
      Path()
        .fill(Color.Brown)
        .commands('M120 150 L480 150 S600 150 480 90 L360 30 S300 0 240 30 L120 90 S0 150 120 150Z')
    }.width('100%')
    .height('40%')
    .backgroundColor(Color.Orange)
    .justifyContent(FlexAlign.SpaceEvenly)
    .alignItems(VerticalAlign.Center)
  }
}

效果图:

点击放大

【总结】

  • 当对组件进行圆角设置时,可以使用borderRadius属性。
  • 当需要对裁剪后的组件进行圆角设置时,borderRadius属性的效果会被覆盖,可以在使用clipShape对组件进行裁剪时,使用PathShape形状按需要进行形状和圆角的裁剪。
  • 当需要绘制带圆角的图形时,可以使用Path组件进行绘制。

更多关于HarmonyOS 鸿蒙Next 使用clipShape进行裁剪后,borderRadius无法生效怎么处理的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS 鸿蒙Next 使用clipShape进行裁剪后,borderRadius无法生效怎么处理的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next系统中,若使用clipShape进行裁剪后发现borderRadius无法生效,这通常是由于裁剪形状和边框圆角设置之间的层级或应用顺序问题。clipShape用于定义视图的裁剪区域,而borderRadius则用于设置视图的圆角边框。两者在某些情况下可能会相互冲突或覆盖。

解决此问题的方法通常涉及调整裁剪形状和圆角设置的顺序或方式:

  1. 确保clipShapeborderRadius设置在同一层级:在布局或样式定义中,检查并确保clipShapeborderRadius是应用于同一视图或组件,并且没有层级上的冲突。

  2. 调整裁剪形状:如果clipShape设置为矩形或其他非圆形形状,borderRadius可能无法正确应用。尝试将clipShape设置为圆形或调整其参数以兼容圆角设置。

  3. 检查样式优先级:在样式定义中,确保没有其他样式或属性覆盖borderRadius的设置。

  4. 使用代码动态设置:如果静态布局定义无法解决问题,尝试在代码中动态设置clipShapeborderRadius,以确保正确的应用顺序和效果。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部