HarmonyOS 鸿蒙Next 跨文件样式复用和组件复用案例

发布于 1周前 作者 wuwangju 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 跨文件样式复用和组件复用案例 HarmonyOS Next应用开发案例(持续更新中……)

本案例完整代码,请访问:代码仓库

介绍

本示例主要介绍了跨文件样式复用和组件复用的场景。在应用开发中,我们通常需要使用相同功能和样式的ArkUI组件,例如购物页面中会使用相同样式的Button按钮、Text显示文字,我们常用的方法是抽取公共样式或者封装成一个自定义组件到公共组件库中以减少冗余代码。

效果图预览

效果图

使用说明:

  1. 点击购物车页面的list列表跳转商品详情页。
  2. 两个页面的button组件、text组件、Image等组件复用相同的样式。
  3. 购物车页面使用了自定义封装的Image+Text的图文复合组件。

实现思路

一、跨文件样式复用

适用场景:当需要向外提供单一组件的样式定制效果时,推荐使用这种方案。使用方在调用接口时,编码量相对方式二更少,仅需几行即可完成调用,使用便捷。

  1. 提供方创建AttributeModifier接口的实现类。
// attributeModifier.ets

/*
  自定义class实现Text的AttributeModifier接口
*/
export class CommodityText implements AttributeModifier<TextAttribute> {
  textType: TextType = TextType.TYPE_ONE;
  textSize: number = 15;

  constructor(textType: TextType, textSize: number) {
    this.textType = textType;
    this.textSize = textSize;
  }

  applyNormalAttribute(instance: TextAttribute): void {
    if (this.textType === TextType.TYPE_ONE) {
      instance.fontSize(this.textSize);
      instance.fontColor($r('app.color.orange'));
      instance.fontWeight(FontWeight.Bolder);
      instance.width($r('app.string.max_size'));
    } else if (this.textType === TextType.TYPE_TWO) {
      instance.fontSize(this.textSize);
      instance.fontWeight(FontWeight.Bold);
      instance.fontColor($r('sys.color.ohos_id_counter_title_font_color'));
      instance.width($r('app.string.max_size'));
    } else if (this.textType === TextType.TYPE_Three) {
      instance.fontColor(Color.Gray);
      instance.fontSize(this.textSize);
      instance.fontWeight(FontWeight.Normal);
      instance.width($r('app.string.max_size'));
    } else if (this.textType === TextType.TYPE_FOUR) {
      instance.fontSize(this.textSize);
      instance.fontColor($r('app.color.orange'));
      instance.textAlign(TextAlign.Center);
      instance.border({ width: $r('app.float.float_1'), color: $r('app.color.orange'), style: BorderStyle.Solid });
      instance.margin({ right: $r('app.float.float_10') });
    }
  }
}
/*
  枚举文本类型
*/
export enum TextType {
  TYPE_ONE,
  TYPE_TWO,
  TYPE_Three,
  TYPE_FOUR
}
  1. 使用方创建提供方的AttributeModifier实现类实例,并作为系统组件attributeModifier属性方法的参数传入。
// ShoppingCart.ets
import { CommodityText } from '../common/attributeModifier';

@Component
export struct Details {
  // 使用方创建提供方的AttributeModifier实现类实例
  @State textOne: CommodityText = new CommodityText(TextType.TYPE_ONE, 15);
  ...

  build(){
    ...
    Text($r('app.string.store_name'))
      // TODO:知识点:将入参的AttributeModifier类实例与系统组件绑定
      .attributeModifier(this.textOne)
      .fontColor($r('sys.color.ohos_id_counter_title_font_color'))
    ...
  }
}

// Details.ets
import { CommodityText } from '../common/attributeModifier';

@Component
export struct Details {
  // 使用方创建提供方的AttributeModifier实现类实例
  @State textOne: MyTextModifier = new MyTextModifier(TextType.TYPE_ONE, 30);
  ...

  build(){
    ...
    Text($r('app.string.commodity_price'))
      // 动态设置组件样式
      .attributeModifier(this.textOne)
      .width($r('app.float.float_100'))
    ...
  }
}

二、跨文件组件复用

适用场景:适用于多个原生组件结合的场景,如Image+Text等复合自定义组件。

  1. 提供方在公共组件库中创建公用的自定义组件,该组件支持外部传入attributeModifier属性。
// CommonText.ets

/**
 * 自定义封装图文组件
 */
@Component
export struct ImageText {
  @State item: string | Resource = $r('app.string.text');
  @State textOneContent: string | Resource = $r('app.string.text');
  @State textTwoContent: string | Resource = $r('app.string.text');
  @State textThreeContent: string | Resource = $r('app.string.text');
  @State imageSrc: PixelMap | ResourceStr | DrawableDescriptor = $r('app.media.icon');
  // TODO:知识点:接受外部传入的AttributeModifier类实例,可以只定制部分组件,选择性传入参数。
  @State textOne: AttributeModifier<TextAttribute> = new TextModifier();
  @State textTwo: AttributeModifier<TextAttribute> = new TextModifier();
  @State textThree: AttributeModifier<TextAttribute> = new TextModifier();
  @State imageModifier: AttributeModifier<ImageAttribute> = new ImageModifier();
  @State checkboxModifier: AttributeModifier<CheckboxAttribute> = new CheckboxModifier();

  build() {
    Row() {
      Row() {
        Checkbox()
          .attributeModifier(this.checkboxModifier)

        // TODO:知识点:AttributeModifier不支持入参为CustomBuilder或Lamda表达式的属性,且不支持事件和手势。image只能单独通过入参传递使用。
        Image(this.imageSrc)
          .attributeModifier(this.imageModifier)
      }

      .margin({ right: $r('app.float.float_10'), bottom: $r('app.float.float_15') })

      Column({ space: COLUMN_SPACE }) {
        // TODO:知识点:将入参的AttributeModifier类实例与系统组件绑定
        Text(this.item)
          .attributeModifier(this.textTwo)

        Text(this.textThreeContent)
          .attributeModifier(this.textThree)

        CommonText({ textFour: new TextModifier() })

        Text(this.textOneContent)
          .attributeModifier(this.textOne)
          .fontColor($r('app.color.orange'))
      }
    }
    .padding({ top: $r('app.float.float_5') })
    .width($r('app.string.max_size'))
    .height($r('app.string.max_size'))
  }
}

/*
  自定义class实现image的AttributeModifier接口,用于初始化
*/
class ImageModifier implements AttributeModifier<ImageAttribute> {
  applyNormalAttribute(instance: ImageAttribute): void {
    instance.width($r('app.float.float_100'));
    instance.height($r('app.float.float_100'));
  }
}

/*
  自定义class实现text的AttributeModifier接口,用于初始化
*/
class TextModifier implements AttributeModifier<TextAttribute> {
  applyNormalAttribute(instance: TextAttribute): void {
    instance.fontSize($r('app.float.float_12'));
    instance.fontColor($r('app.color.orange'));
    instance.textAlign(TextAlign.Center);
    instance.border({ width: $r('app.float.float_1'), color: $r('app.color.orange'), style: BorderStyle.Solid });
    instance.margin({ right: $r('app.float.float_10') });
  }
}

/*
  自定义class实现checkbox的AttributeModifier接口,用于初始化
*/
class CheckboxModifier implements AttributeModifier<CheckboxAttribute> {
  applyNormalAttribute(instance: CheckboxAttribute): void {
    instance.width($r('app.float.float_15'));
    instance.height($r('app.float.float_15'));
  }
}
  1. 使用方分别实现Image组件和Text组件的AttributeModifier接口实现类。
/*
  自定义class实现Image组件的AttributeModifier接口
*/
export class ImageModifier implements AttributeModifier<ImageAttribute> {
  width: Length | Resource = 0;
  height: Length | Resource = 0;

  constructor(width: Length | Resource, height: Length | Resource) {
    this.width = width;
    this.height = height;
  }

  applyNormalAttribute(instance: ImageAttribute): void {
    instance.width(this.width);
    instance.height(this.height);
    instance.borderRadius($r('app.float.float_10'));
  }
}

/*
  自定义class实现Text的AttributeModifier接口
*/
export class CommodityText implements AttributeModifier<TextAttribute> {
  ...
}
  1. 使用方创建Image组件和Text组件的AttributeModifier接口实现类实例,并作为提供方自定义组件CustomImageText的入参传入。
@Component
export struct ShoppingCart {
  // TODO:知识点:使用方创建Image组件和Text组件的AttributeModifier接口实现类实例
  @State textOne: CommodityText = new CommodityText(TextType.TYPE_ONE, 15);
  @State textTwo: CommodityText = new CommodityText(TextType.TYPE_TWO, 17);
  @State textThree: CommodityText = new CommodityText(TextType.TYPE_Three, 15);
  @State imageModifier: ImageModifier = new ImageModifier(100, 100);
  @State checkboxModifier: CheckboxModifier = new CheckboxModifier();

  build() {
    ...
    // AttributeModifier实例作为提供方自定义组件ImageText的入参传入。
    ImageText({
      item: item,
      textOne: this.textOne,
      textTwo: this.textTwo,
      textThree: this.textThree,
      imageModifier: this.imageModifier,
      imageSrc: $r('app.media.icon'),
      checkboxModifier: this.checkboxModifier,
      textOneContent: $r('app.string.commodity_price'),
      textTwoContent: $r('app.string.commodity_name'),
      textThreeContent: $r('app.string.commodity_model')
      })
    ... 
  }
}

高性能知识点

本示例使用了动态属性设置和自定义封装公共组件,实现了跨文件样式和组件复用,减少了工程很多冗余的代码。

工程结构 & 模块类型

dynamicattributes
|---common
|   |---AttributeModifier.ets               // 自定义AttributeModifier接口
|   |---CommonText.ets                      // 自定义组件封装
|   |---LazyForEach.ets                     // 懒加载
|---pages
|   |---ShoppingCart.ets                    // 页面一:购物车
|   |---Details.ets                         // 页面二:详情页

模块依赖

本示例依赖 路由管理模块

参考资料


更多关于HarmonyOS 鸿蒙Next 跨文件样式复用和组件复用案例的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

简直让人想吐, 这啥玩意儿样式复用. @Extend@Styles支持export是最为简化的样式复用了.

更多关于HarmonyOS 鸿蒙Next 跨文件样式复用和组件复用案例的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next系统中,跨文件样式复用和组件复用是提升开发效率和代码可维护性的重要手段。

跨文件样式复用:

HarmonyOS支持通过全局样式或自定义样式实现跨文件样式复用。开发者可以在一个样式文件中定义全局或自定义样式,然后在其他文件中通过引用该样式实现复用。这避免了在不同文件中重复定义相同样式的问题,提高了代码的一致性和可维护性。

组件复用:

组件复用主要通过自定义组件实现。开发者可以将常用的UI元素、逻辑等封装成一个自定义组件,然后在其他页面中通过引用该组件实现复用。这不仅减少了重复代码,还提高了开发效率。同时,自定义组件还可以接受外部参数,实现更灵活的复用。

在实现跨文件样式复用和组件复用时,开发者需要注意样式的命名规范、组件的接口设计等,以确保复用时的正确性和灵活性。

如果在使用HarmonyOS鸿蒙Next系统进行跨文件样式复用和组件复用时遇到问题,可能是由于样式或组件的引用方式不正确、命名冲突等原因造成的。请仔细检查相关代码,确保样式和组件的引用正确无误。

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

回到顶部