fanmingyou

添加自定义组件:

单列组件:SINGLE_COLUMN
 样式:
 'Single_Column-01', // 大卡横屏视频:视频、直播
 'Single_Column-02', // 活动卡:活动

轮播组件,即Banner/轮播大图/焦点图/自动滑动
  样式:
 'Carousel_Layout-01', // 通用轮播卡:视频、直播、活动、专题、榜单、外链
@@ -7,6 +7,14 @@ @@ -7,6 +7,14 @@
7 7
8 8
9 ## 环境搭建 9 ## 环境搭建
  10 +1.下载/解压开发工具:统一用DevEco Studio 4.0.3.700(SP1)-API10(windows操作系统/mac操作系统)(2023-12-25)
  11 +2.按照解压目录中的【Studio环境配置指导.docx】文档安装/配置开发环境/并创建并运行HelloWorld工程(暂时用开发者个人签名,最终发布时最好用企业签名)。
  12 +3.项目英文名称【Sight_Harmony】;中文名称【网达编排】;包名【com.wondertek.sight】
  13 +4.Compile SDK: 4.0.0(API10)
  14 +5.支持设备类型:Phone/Tablet/2in1
  15 +6.主模块/入口模块默认名称:entry
  16 +7.模型能力(Model):Stage模型(官方推荐模型能力)
  17 +8.nodejs版本:nodejs-16.20.1(DevEco开发环境默认版本)
10 18
11 ### 软件要求 19 ### 软件要求
12 20
@@ -73,6 +81,9 @@ import axios from '@ohos/axios'; @@ -73,6 +81,9 @@ import axios from '@ohos/axios';
73 同理,在mlayout模块使用三方库@ohos/lottie(V2.0.7) 81 同理,在mlayout模块使用三方库@ohos/lottie(V2.0.7)
74 https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Flottie 82 https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Flottie
75 83
  84 +## Previewer使用
  85 +在自定义组件上,再加一个@Entry装饰器,再给参数设置必要的数据,即可用Previewer查看布局展示效果
  86 +
76 ## 代码结构解读 87 ## 代码结构解读
77 88
78 ## 总结 89 ## 总结
1 -import { CompDTO, CompStyle, GroupDTO, ItemBean, ItemDTO, ViewType } from 'wdBean';  
2 -import { CompUtils, EmptyComponent, ErrorComponent, 1 +import { CompDTO, CompStyle, GroupDTO, ViewType } from 'wdBean';
  2 +import {
  3 + BannerComponent,
  4 + EmptyComponent,
  5 + ErrorComponent,
3 GridLayout01Component, 6 GridLayout01Component,
4 - LabelComponent, LoadingComponent,  
5 - SingleRow03Component, } from 'wdComponent'; 7 + LabelComponent,
  8 + LoadingComponent,
  9 + SingleColumnComponent,
  10 + SingleRow03Component,
  11 +} from 'wdComponent';
6 import { CommonConstants } from 'wdConstant'; 12 import { CommonConstants } from 'wdConstant';
7 import { LazyDataSource, Logger, StringUtils } from 'wdKit'; 13 import { LazyDataSource, Logger, StringUtils } from 'wdKit';
8 14
9 -  
10 const TAG = 'PageComponent'; 15 const TAG = 'PageComponent';
11 16
12 @Component 17 @Component
@@ -14,7 +19,6 @@ export struct PageComponent { @@ -14,7 +19,6 @@ export struct PageComponent {
14 @Prop viewType: number = ViewType.LOADED; 19 @Prop viewType: number = ViewType.LOADED;
15 // Group数据及子组件数据 20 // Group数据及子组件数据
16 @State groupList: LazyDataSource<GroupDTO> = new LazyDataSource(); 21 @State groupList: LazyDataSource<GroupDTO> = new LazyDataSource();
17 - @State isRefreshing: boolean = false  
18 22
19 build() { 23 build() {
20 if (this.viewType == ViewType.LOADING) { 24 if (this.viewType == ViewType.LOADING) {
@@ -24,7 +28,6 @@ export struct PageComponent { @@ -24,7 +28,6 @@ export struct PageComponent {
24 } else if (this.viewType == ViewType.EMPTY) { 28 } else if (this.viewType == ViewType.EMPTY) {
25 EmptyComponent() 29 EmptyComponent()
26 } else { 30 } else {
27 - Refresh({ refreshing: this.isRefreshing }) {  
28 List() { 31 List() {
29 LazyForEach(this.groupList, (groupDTO: GroupDTO, groupIndex: number) => { 32 LazyForEach(this.groupList, (groupDTO: GroupDTO, groupIndex: number) => {
30 ListItem() { 33 ListItem() {
@@ -38,29 +41,21 @@ export struct PageComponent { @@ -38,29 +41,21 @@ export struct PageComponent {
38 } 41 }
39 .cachedCount(5) 42 .cachedCount(5)
40 .height(CommonConstants.FULL_PARENT) 43 .height(CommonConstants.FULL_PARENT)
41 -  
42 - // .padding({  
43 - // bottom: (this.currentNavIndex === 0 || this.currentNavIndex === 1) ? $r('app.float.search_bar_height') : 0  
44 - // }) // 当页面顶部有搜索bar时,页面的list增加bottom的padding为搜索bar的高度  
45 - }  
46 - .onRefreshing(() => {  
47 - this.isRefreshing = true  
48 - // this.sendRequest(true)  
49 - // setTimeout(() => {  
50 - // this.isRefreshing = false  
51 - // }, 2000)  
52 - })  
53 } 44 }
54 } 45 }
55 46
56 @Builder 47 @Builder
57 componentBuilder(compDTO: CompDTO, groupIndex: number, compIndex: number) { 48 componentBuilder(compDTO: CompDTO, groupIndex: number, compIndex: number) {
58 if (compDTO.compStyle === CompStyle.Label_03) { 49 if (compDTO.compStyle === CompStyle.Label_03) {
59 - LabelComponent({ label: CompUtils.getLabelTitle(compDTO.extraData) })  
60 - } else if(compDTO.compStyle === CompStyle.Single_Row_03){  
61 - SingleRow03Component({dataList: compDTO.operDataList})  
62 - } else if(compDTO.compStyle === CompStyle.Grid_Layout_01){  
63 - GridLayout01Component({dataList: compDTO.operDataList}) 50 + LabelComponent({ compDTO: compDTO })
  51 + } else if (compDTO.compStyle === CompStyle.Carousel_Layout_01) {
  52 + BannerComponent({ compDTO: compDTO })
  53 + } else if (compDTO.compStyle === CompStyle.Single_Row_03) {
  54 + SingleRow03Component({ dataList: compDTO.operDataList })
  55 + } else if (compDTO.compStyle === CompStyle.Single_Column_01 || compDTO.compStyle === CompStyle.Single_Column_02) {
  56 + SingleColumnComponent({ compDTO: compDTO })
  57 + } else if (compDTO.compStyle === CompStyle.Grid_Layout_01) {
  58 + GridLayout01Component({ dataList: compDTO.operDataList })
64 } else { 59 } else {
65 // todo:组件未实现 / Component Not Implemented 60 // todo:组件未实现 / Component Not Implemented
66 Text(compDTO.compStyle) 61 Text(compDTO.compStyle)
1 -# This file is automatically generated by DevEco Studio.  
2 -# Do not modify this file -- YOUR CHANGES WILL BE ERASED!  
3 -#  
4 -# This file should *NOT* be checked into Version Control Systems,  
5 -# as it contains information specific to your local configuration.  
6 -#  
7 -# For customization when using a Version Control System, please read the header note.  
8 -nodejs.dir=D:/node  
9 -hwsdk.dir=D:/huawei/Sdk-4.0.700  
@@ -7,6 +7,8 @@ export { NetDataStatusType } from './src/main/ets/enum/NetDataStatusType'; @@ -7,6 +7,8 @@ export { NetDataStatusType } from './src/main/ets/enum/NetDataStatusType';
7 7
8 export { ViewType } from './src/main/ets/enum/ViewType'; 8 export { ViewType } from './src/main/ets/enum/ViewType';
9 9
  10 +export { DelayTimeEnum } from './src/main/ets/enum/DelayTimeEnum';
  11 +
10 // entity 12 // entity
11 export { ItemDTO } from './src/main/ets/bean/ItemDTO'; 13 export { ItemDTO } from './src/main/ets/bean/ItemDTO';
12 14
@@ -16,9 +16,9 @@ export interface CompDTO { @@ -16,9 +16,9 @@ export interface CompDTO {
16 linkUrl: string; 16 linkUrl: string;
17 // meddleDataList: any[]; 17 // meddleDataList: any[];
18 name: string; 18 name: string;
19 - objectId: string;  
20 - objectTitle: string;  
21 - // objectType?: any; 19 + objectId: string; // 跳转页面id?
  20 + objectTitle: string; // comp标题
  21 + // objectType?: any; // 跳转类型,枚举:
22 operDataList: ContentDTO[]; // 运营数据列表【正常运营配置的强运营数据,部分推荐场景的配置(自动源兜底数据)】 22 operDataList: ContentDTO[]; // 运营数据列表【正常运营配置的强运营数据,部分推荐场景的配置(自动源兜底数据)】
23 // pageId?: any; 23 // pageId?: any;
24 posterSize: string; 24 posterSize: string;
@@ -2,21 +2,21 @@ @@ -2,21 +2,21 @@
2 * 组件Style/展示样式 2 * 组件Style/展示样式
3 */ 3 */
4 export const enum CompStyle { 4 export const enum CompStyle {
5 - Label_03 = 'Label-03', // 标题  
6 - Carousel_Layout_01 = 'Carousel_Layout-01',  
7 - Carousel_Layout_02 = 'Carousel_Layout-02',  
8 - Single_Row_01 = 'Single_Row-01',  
9 - Single_Row_02 = 'Single_Row-02',  
10 - Single_Row_03 = 'Single_Row-03',  
11 - Single_Row_04 = 'Single_Row-04',  
12 - Single_Row_05 = 'Single_Row-05',  
13 - Single_Column_01 = 'Single_Column-01',  
14 - Single_Column_02 = 'Single_Column-02',  
15 - Single_Column_03 = 'Single_Column-03',  
16 - Single_Column_04 = 'Single_Column-04',  
17 - Single_Column_05 = 'Single_Column-05',  
18 - Single_Column_06 = 'Single_Column-06',  
19 - Grid_Layout_01 = 'Grid_Layout-01',  
20 - Grid_Layout_02 = 'Grid_Layout-02',  
21 - Masonry_Layout_01 = 'Masonry_Layout-01', 5 + Label_03 = 'Label-03', // 标题卡:icon+文字
  6 + Carousel_Layout_01 = 'Carousel_Layout-01', // 通用轮播卡:视频、直播、活动、专题、榜单、外链
  7 + Carousel_Layout_02 = 'Carousel_Layout-02', // 直播轮播卡:直播
  8 + Single_Row_01 = 'Single_Row-01', // 三格方形小卡(排名):专题、活动
  9 + Single_Row_02 = 'Single_Row-02', // 通用横划卡:视频、直播、专题
  10 + Single_Row_03 = 'Single_Row-03', // 直播横划卡:直播
  11 + Single_Row_04 = 'Single_Row-04', // 三格方形小卡:专题、活动
  12 + Single_Row_05 = 'Single_Row-05', // 专题横划卡:视频、直播、专题、活动、榜单、外链
  13 + Single_Column_01 = 'Single_Column-01', // 大卡横屏视频:视频、直播
  14 + Single_Column_02 = 'Single_Column-02', // 活动卡:活动
  15 + Single_Column_03 = 'Single_Column-03', // 地域榜单:榜单
  16 + Single_Column_04 = 'Single_Column-04', // 大卡横屏(带背景):视频、直播
  17 + Single_Column_05 = 'Single_Column-05', // 海报图卡:/
  18 + Single_Column_06 = 'Single_Column-06', // 留言板卡:/
  19 + Grid_Layout_01 = 'Grid_Layout-01', // 横屏宫格卡:视频、直播
  20 + Grid_Layout_02 = 'Grid_Layout-02', // 竖屏宫格卡:视频、直播、榜单
  21 + Masonry_Layout_01 = 'Masonry_Layout-01', // 双列瀑布流/瀑布流卡:视频、直播、专题、活动
22 } 22 }
@@ -2,10 +2,10 @@ @@ -2,10 +2,10 @@
2 * 组件Type/展示类型 2 * 组件Type/展示类型
3 */ 3 */
4 export const enum CompType { 4 export const enum CompType {
5 - LABEL = 'LABEL', // 标题  
6 - CAROUSEL_LAYOUT = 'CAROUSEL_LAYOUT', // 轮播大图,即Banner/焦点图  
7 - SINGLE_ROW = 'SINGLE_ROW', //  
8 - SINGLE_COLUMN = 'SINGLE_COLUMN', //  
9 - GRID_LAYOUT = 'GRID_LAYOUT', //  
10 - MASONRY_LAYOUT = 'MASONRY_LAYOUT', // 5 + LABEL = 'LABEL', // 标题组件
  6 + CAROUSEL_LAYOUT = 'CAROUSEL_LAYOUT', // 轮播组件,即Banner/焦点图
  7 + SINGLE_ROW = 'SINGLE_ROW', // 单行组件
  8 + SINGLE_COLUMN = 'SINGLE_COLUMN', // 单列组件
  9 + GRID_LAYOUT = 'GRID_LAYOUT', // 网格组件
  10 + MASONRY_LAYOUT = 'MASONRY_LAYOUT', // 瀑布流组件
11 } 11 }
@@ -6,5 +6,6 @@ export const enum DelayTimeEnum { @@ -6,5 +6,6 @@ export const enum DelayTimeEnum {
6 DURATION_100 = 100, // 50毫秒 6 DURATION_100 = 100, // 50毫秒
7 DURATION_1000 = 1000, // 1秒/1000ms 7 DURATION_1000 = 1000, // 1秒/1000ms
8 DURATION_2000 = 2000, // 2秒/2000ms 8 DURATION_2000 = 2000, // 2秒/2000ms
9 - LAUNCHER_DELAY_TIME = 1500 // 1.5秒 9 + LAUNCHER_DELAY_TIME = 1500, // 1.5秒
  10 + INTERVAL_4000 = 4000, //4秒
10 } 11 }
@@ -8,6 +8,10 @@ export { LoadingComponent } from "./src/main/ets/components/LoadingComponent" @@ -8,6 +8,10 @@ export { LoadingComponent } from "./src/main/ets/components/LoadingComponent"
8 8
9 export { LabelComponent } from "./src/main/ets/components/LabelComponent" 9 export { LabelComponent } from "./src/main/ets/components/LabelComponent"
10 10
11 -export {SingleRow03Component} from "./src/main/ets/components/SingleRow03Component" 11 +export { BannerComponent } from "./src/main/ets/components/BannerComponent"
12 12
13 -export {GridLayout01Component} from "./src/main/ets/components/GridLayout01Component"  
  13 +export { SingleRow03Component } from "./src/main/ets/components/SingleRow03Component"
  14 +
  15 +export { SingleColumnComponent } from "./src/main/ets/components/SingleColumnComponent"
  16 +
  17 +export { GridLayout01Component } from "./src/main/ets/components/GridLayout01Component"
  1 +import { CompDTO, ContentDTO, DelayTimeEnum } from 'wdBean';
  2 +import { CommonConstants } from 'wdConstant';
  3 +import { Logger } from 'wdKit';
  4 +import { CompUtils } from '../utils/CompUtils';
  5 +import { EmptyComponent } from './EmptyComponent';
  6 +
  7 +const TAG = 'BannerComponent';
  8 +
  9 +/**
  10 + * 轮播组件,即Banner/轮播大图/焦点图/自动滑动
  11 + * 样式:
  12 + * 'Carousel_Layout-01', // 通用轮播卡:视频、直播、活动、专题、榜单、外链
  13 + */
  14 +@Component
  15 +export struct BannerComponent {
  16 + @StorageLink('currentBreakpoint') @Watch('watchCurrentBreakpoint') currentBreakpoint: string = 'xs';
  17 + @State compDTO: CompDTO = {} as CompDTO
  18 +
  19 + watchCurrentBreakpoint() {
  20 + Logger.info(TAG, `watchCurrentBreakpoint, this.currentBreakpoint: ${this.currentBreakpoint}`);
  21 + }
  22 +
  23 + aboutToAppear() {
  24 + Logger.info(TAG, `aboutToAppear, beanList:${this.compDTO?.operDataList?.length}, currentBreakpoint:${this.currentBreakpoint}`);
  25 + }
  26 +
  27 + aboutToDisappear() {
  28 + Logger.info(TAG, 'aboutToDisappear');
  29 + }
  30 +
  31 + onPageShow() {
  32 + Logger.info(TAG, 'onPageShow');
  33 + }
  34 +
  35 + onPageHide() {
  36 + Logger.info(TAG, 'onPageHide');
  37 + }
  38 +
  39 + onBackPress() {
  40 + Logger.info(TAG, 'onBackPress');
  41 + }
  42 +
  43 + build() {
  44 + if (this.compDTO && this.compDTO?.operDataList?.length > 0) {
  45 + Swiper() {
  46 + ForEach(this.compDTO?.operDataList, (item: ContentDTO, index: number) => {
  47 + this.buildItemBanner01(item, index)
  48 + })
  49 + }
  50 + .displayCount(1) // 仅展示1个图片
  51 + .cachedCount(2)
  52 + .index(1) // The default index of Swiper.
  53 + .autoPlay(true)
  54 + .interval(DelayTimeEnum.INTERVAL_4000)
  55 + .indicator(Indicator.dot()
  56 + .right(5)
  57 + .itemWidth(4)
  58 + .itemHeight(4)
  59 + .selectedItemWidth(10)
  60 + .selectedItemHeight(6))
  61 + .loop(true)
  62 + .duration(DelayTimeEnum.DURATION_1000)
  63 + .vertical(false)
  64 + .curve(Curve.Linear)
  65 + .onChange((index: number) => {
  66 + Logger.info(TAG, `Swiper onChange index : ${index}`);
  67 + })
  68 + } else {
  69 + EmptyComponent({ emptyHeight: 200 })
  70 + }
  71 + }
  72 +
  73 + // public buildDisplayCount(): number {
  74 + // return new BreakPointType({ xs: 1, sm: 1, md: 2, lg: 3 }).getValue(this.currentBreakpoint)
  75 + // }
  76 +
  77 + /**
  78 + * 组件项
  79 + *
  80 + * @param programmeBean item 组件项
  81 + */
  82 + @Builder
  83 + buildItemBanner01(item: ContentDTO, index: number) {
  84 + RelativeContainer() {
  85 + Image(item.hImageUrl)
  86 + .width(CommonConstants.FULL_PARENT)
  87 + .height(CommonConstants.FULL_PARENT)
  88 + .objectFit(ImageFit.Cover)
  89 + .borderRadius($r("app.float.border_radius_6"))
  90 + .alignRules({
  91 + top: { anchor: '__container__', align: VerticalAlign.Top },
  92 + left: { anchor: '__container__', align: HorizontalAlign.Start }
  93 + })
  94 + .id('img_cover')
  95 +
  96 + // if (item.topLeftTipImgUrl) {
  97 + // Image(item.topLeftTipImgUrl)
  98 + // .width(CompCornerUtil.getCornerWidth(this.currentBreakpoint))
  99 + // .aspectRatio(CompCornerUtil.ASPECT_RATIO_75_45)
  100 + // .margin({ left: 6 })
  101 + // .objectFit(ImageFit.Cover)
  102 + // .alignRules({
  103 + // top: { anchor: '__container__', align: VerticalAlign.Top },
  104 + // left: { anchor: '__container__', align: HorizontalAlign.Start }
  105 + // })
  106 + // .id('img_corner_top_Left')
  107 + // }
  108 +
  109 + Text(item.title)
  110 + .width(CommonConstants.FULL_PARENT)
  111 + .height(39)
  112 + .padding({ left: 8, right: 69, bottom: 8 })
  113 + .fontColor(Color.White)
  114 + .fontSize($r('app.float.font_size_16'))
  115 + .fontWeight(FontWeight.Medium)
  116 + .textAlign(TextAlign.Start)
  117 + .align(Alignment.Bottom)
  118 + .maxLines(CompUtils.MAX_LINES_1)
  119 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  120 + .linearGradient({
  121 + direction: GradientDirection.Top, // 渐变方向:to Top/从下往上
  122 + colors: [[0x7508111A, 0.0], [0x7508111A, 0.3], [Color.Transparent, 1.0]]
  123 + })
  124 + .alignRules({
  125 + bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
  126 + left: { anchor: '__container__', align: HorizontalAlign.Start }
  127 + })
  128 + .id('txt_name')
  129 + }
  130 + .width(CommonConstants.FULL_PARENT)
  131 + .aspectRatio(CompUtils.ASPECT_RATIO_2_1)
  132 + .hoverEffect(HoverEffect.Scale)
  133 + .onClick((event: ClickEvent) => {
  134 + Logger.info(TAG, `BannerComponent onClick event index: ${index}`);
  135 + })
  136 + }
  137 +}
  1 +import { ContentDTO } from 'wdBean';
  2 +import { CommonConstants } from 'wdConstant';
  3 +import { Logger } from 'wdKit';
  4 +import { CompUtils } from '../utils/CompUtils';
  5 +
  6 +const TAG = 'CardView';
  7 +
  8 +/**
  9 + * 卡片结构:上下结构
  10 + * 卡片宽度:充满父窗口
  11 + * 卡片高度,由3部分:
  12 + * 1.图片宽高比为16:9;
  13 + * 2.一行title文字高度
  14 + * 3.一行author头像及名称高度
  15 + */
  16 +@Component
  17 +export struct SingleColumn01CardView {
  18 + private item: ContentDTO = {} as ContentDTO;
  19 + private index: number = -1;
  20 +
  21 + build() {
  22 + Column() {
  23 + RelativeContainer() {
  24 + // 1.海报图片
  25 + Image(this.item.hImageUrl)
  26 + .width(CommonConstants.FULL_PARENT)
  27 + .aspectRatio(CompUtils.ASPECT_RATIO_16_9)
  28 + .borderRadius($r("app.float.border_radius_6"))
  29 + .alignRules({
  30 + top: { anchor: '__container__', align: VerticalAlign.Top },
  31 + left: { anchor: '__container__', align: HorizontalAlign.Start }
  32 + })
  33 + .id('img_cover')
  34 +
  35 + // 2.视频时长(Duration)
  36 + if (this.item.startTime) {
  37 + Text(this.item.startTime)
  38 + .width(CommonConstants.FULL_PARENT)// .height($r('app.float.duration_bg_height'))
  39 + .padding(10)
  40 + .fontColor(Color.White)
  41 + .fontSize($r('app.float.font_size_12'))
  42 + .fontWeight(FontWeight.Normal)
  43 + .textAlign(TextAlign.End)
  44 + .align(Alignment.Center)
  45 + .maxLines(CompUtils.MAX_LINES_1)// .backgroundColor(Color.Red)
  46 + .linearGradient({
  47 + direction: GradientDirection.Top, // 渐变方向:to Top/从下往上
  48 + colors: [[0x7508111A, 0.0], [0x7508111A, 0.3], [Color.Transparent, 1.0]]
  49 + })
  50 + .borderRadius($r("app.float.border_radius_6"))
  51 + .alignRules({
  52 + bottom: { anchor: 'img_cover', align: VerticalAlign.Bottom }
  53 + })
  54 + .id('txt_duration')
  55 + }
  56 + }
  57 + .width(CommonConstants.FULL_PARENT)
  58 + .aspectRatio(CompUtils.ASPECT_RATIO_16_9)
  59 +
  60 + // 3.标题1行/title
  61 + Text(this.item.title)
  62 + .width(CommonConstants.FULL_PARENT)
  63 + .margin({ top: 4, left: 6, right: 6 })// .backgroundColor(Color.Brown)
  64 + .fontWeight(FontWeight.Normal)
  65 + .textAlign(TextAlign.Start)
  66 + .fontSize($r('app.float.font_size_14'))
  67 + .fontColor($r('app.color.color_333333'))
  68 + .maxLines(CompUtils.MAX_LINES_1)
  69 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  70 + }
  71 + .padding({ bottom: 8 })
  72 + .backgroundColor(Color.White)
  73 + .borderRadius($r("app.float.border_radius_6"))
  74 + .hoverEffect(HoverEffect.Scale)
  75 + .onClick((event: ClickEvent) => {
  76 + Logger.info(TAG, `SingleColumn01CardView onClick event index: ${this.index}`);
  77 + })
  78 + }
  79 +}
  80 +
  81 +/**
  82 + * 卡片结构:上下结构,上部分再左右结构(左图右文)
  83 + * 卡片宽度:充满父窗口
  84 + * 卡片高度,由2部分组成:
  85 + * 1.左侧图片宽高比为3:4;右侧文本及按钮等
  86 + * 2.最多3行title文字高度
  87 + */
  88 +@Component
  89 +export struct SingleColumn02CardView {
  90 + private item: ContentDTO = {} as ContentDTO;
  91 + private index: number = -1;
  92 +
  93 + build() {
  94 + Column() {
  95 + Row() {
  96 + Image(this.item.vImageUrl)
  97 + .width('38%')
  98 + .aspectRatio(CompUtils.ASPECT_RATIO_3_4)
  99 + .borderRadius($r("app.float.border_radius_6"))
  100 +
  101 + // Blank()
  102 + Column() {
  103 + Text(this.item.title)
  104 + .margin({ right: 20 })
  105 + .fontColor($r('app.color.color_333333'))
  106 + .fontSize($r('app.float.font_size_16'))
  107 + .fontWeight(FontWeight.Bold)// .textAlign(TextAlign.Start)
  108 + .maxLines(CompUtils.MAX_LINES_1)
  109 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  110 +
  111 + if (this.item.heatValue) {
  112 + Text() {
  113 + Span(`热度 `)
  114 + .fontColor($r('app.color.color_666666'))
  115 +
  116 + Span(`${this.item.heatValue}`)
  117 + .fontColor($r('app.color.color_333333'))
  118 + }
  119 + .height(20)
  120 + .margin({ top: 8, right: 20 })
  121 + .fontSize($r('app.float.font_size_14'))
  122 + .maxLines(CompUtils.MAX_LINES_1)
  123 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  124 + }
  125 +
  126 + if (this.item.startTime) {
  127 + Text() {
  128 + Span(`开始 `)
  129 + .fontColor($r('app.color.color_666666'))
  130 + Span(`${this.item.startTime}`)
  131 + .fontColor($r('app.color.color_333333'))
  132 + }
  133 + .height(20)
  134 + .margin({ top: 8, right: 20 })
  135 + .fontSize($r('app.float.font_size_14'))
  136 + .maxLines(CompUtils.MAX_LINES_1)
  137 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  138 + }
  139 +
  140 + if (this.item.endTime) {
  141 + Text() {
  142 + Span(`结束 `)
  143 + .fontColor($r('app.color.color_666666'))
  144 + Span(`${this.item.endTime}`)
  145 + .fontColor($r('app.color.color_333333'))
  146 + }
  147 + .height(20)
  148 + .margin({ top: 8, right: 20 })
  149 + .fontSize($r('app.float.font_size_14'))
  150 + .maxLines(CompUtils.MAX_LINES_1)
  151 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  152 + }
  153 +
  154 + Text('即将开始')
  155 + .width(96)
  156 + .height(34)
  157 + .margin({ top: 15 })
  158 + .backgroundImage($r('app.media.bg_event_status_no_start'))
  159 + .fontColor($r('app.color.color_FE4B05'))
  160 + .fontSize($r('app.float.font_size_14'))
  161 + .textAlign(TextAlign.Center)
  162 + .maxLines(CompUtils.MAX_LINES_1)
  163 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  164 + }
  165 + .width('62%')
  166 + .margin({ left: 12, right: 12, top: 8, bottom: 8 })
  167 + // .backgroundColor(Color.Red)
  168 + .alignItems(HorizontalAlign.Start) // 内容靠左对齐
  169 +
  170 + }
  171 + .width(CommonConstants.FULL_PARENT)
  172 + .alignItems(VerticalAlign.Top)
  173 + // .backgroundColor(Color.Orange)
  174 +
  175 + Text(this.item.description)
  176 + .width(CommonConstants.FULL_PARENT)
  177 + .margin({ top: 4, left: 6, right: 6 })// .backgroundColor(Color.Brown)
  178 + .fontWeight(FontWeight.Normal)
  179 + .textAlign(TextAlign.Start)
  180 + .fontSize($r('app.float.font_size_14'))
  181 + .fontColor($r('app.color.color_666666'))
  182 + .maxLines(CompUtils.MAX_LINES_3)
  183 + .textOverflow({ overflow: TextOverflow.Ellipsis })
  184 + }
  185 + .padding({ bottom: 8 })
  186 + .backgroundColor(Color.White)
  187 + .borderRadius($r("app.float.border_radius_6"))
  188 + .hoverEffect(HoverEffect.Scale)
  189 + .onClick((event: ClickEvent) => {
  190 + Logger.info(TAG, `SingleColumn02CardView onClick event index: ${this.index}`);
  191 + })
  192 + }
  193 +}
1 -import LinkList from '@ohos.util.List';  
2 -import { LabelBean } from 'wdBean'; 1 +import { CompDTO } from 'wdBean';
3 import { CommonConstants } from 'wdConstant'; 2 import { CommonConstants } from 'wdConstant';
4 -import { Logger } from 'wdKit';  
5 -  
6 -import { EmptyComponent } from './EmptyComponent'; 3 +import { CompUtils } from '../utils/CompUtils';
7 4
8 const TAG = 'LabelComponent'; 5 const TAG = 'LabelComponent';
9 6
10 /** 7 /**
11 * 标题/标签组件(暂时仅展示主标题,不展示子标题) 8 * 标题/标签组件(暂时仅展示主标题,不展示子标题)
12 - * LABEL-01 9 + * Label-03
13 * 重磅推荐/精选/电视剧/电影/综艺/短剧/更多>/ 10 * 重磅推荐/精选/电视剧/电影/综艺/短剧/更多>/
14 - * 1.只有一个LABEL主标题(如重磅推荐)  
15 - * 2.左右共两个LABEL(左边【电影】是主标题/右边【上海电影节】是子标题)  
16 */ 11 */
  12 +@Entry
17 @Component 13 @Component
18 export struct LabelComponent { 14 export struct LabelComponent {
19 - @State label: string = ''; 15 + @State compDTO: CompDTO = {} as CompDTO
20 16
21 build() { 17 build() {
22 Row() { 18 Row() {
23 - Text(this.label) 19 + Text(CompUtils.getLabelTitle(this.compDTO.extraData))
24 .width(CommonConstants.FULL_PARENT) 20 .width(CommonConstants.FULL_PARENT)
25 .padding({ 21 .padding({
26 left: $r('app.float.main_margin'), 22 left: $r('app.float.main_margin'),
@@ -30,8 +26,7 @@ export struct LabelComponent { @@ -30,8 +26,7 @@ export struct LabelComponent {
30 }) 26 })
31 .fontSize($r('app.float.normal_text_size')) 27 .fontSize($r('app.float.normal_text_size'))
32 .fontWeight(FontWeight.Bold) 28 .fontWeight(FontWeight.Bold)
33 - .maxLines(1)  
34 - // .backgroundColor(Color.Yellow) 29 + .maxLines(1)// .backgroundColor(Color.Yellow)
35 .textOverflow({ overflow: TextOverflow.Ellipsis }) // 超出的部分显示省略号。 30 .textOverflow({ overflow: TextOverflow.Ellipsis }) // 超出的部分显示省略号。
36 } 31 }
37 .width(CommonConstants.FULL_PARENT) 32 .width(CommonConstants.FULL_PARENT)
  1 +import { CompDTO, CompStyle, ContentDTO } from 'wdBean';
  2 +import { Logger } from 'wdKit';
  3 +import { SingleColumn01CardView, SingleColumn02CardView } from './CardView';
  4 +import { EmptyComponent } from './EmptyComponent';
  5 +
  6 +const TAG = 'SingleColumn01Component';
  7 +
  8 +/**
  9 + * 单列组件:SINGLE_COLUMN
  10 + * 支持样式:
  11 + * 'Single_Column-01', // 大卡横屏视频:视频、直播
  12 + * 'Single_Column-02', // 活动卡:活动
  13 + */
  14 +@Component
  15 +export struct SingleColumnComponent {
  16 + @State compDTO: CompDTO = {} as CompDTO
  17 + private compStyle: string = CompStyle.Single_Column_01;
  18 +
  19 + aboutToAppear() {
  20 + this.compStyle = this.compDTO.compStyle
  21 + Logger.info(TAG, `aboutToAppear beanList: ${this.compDTO?.operDataList?.length}`);
  22 + }
  23 +
  24 + aboutToDisappear() {
  25 + Logger.info(TAG, 'aboutToDisappear');
  26 + }
  27 +
  28 + onPageShow() {
  29 + Logger.info(TAG, 'onPageShow');
  30 + }
  31 +
  32 + onPageHide() {
  33 + Logger.info(TAG, 'onPageHide');
  34 + }
  35 +
  36 + onBackPress() {
  37 + Logger.info(TAG, 'onBackPress');
  38 + }
  39 +
  40 + build() {
  41 + if (this.compDTO && this.compDTO?.operDataList?.length > 0) {
  42 + List({ space: 4 }) {
  43 + ForEach(this.compDTO?.operDataList, (item: ContentDTO, index: number) => {
  44 + ListItem() {
  45 + this.buildItemView(item, index)
  46 + }
  47 + })
  48 + }
  49 + .margin({ left: $r('app.float.main_margin'), right: $r('app.float.main_margin'), bottom: 8 })
  50 + .listDirection(Axis.Vertical)
  51 + .lanes(1) // 行/列数,一列
  52 + .scrollBar(BarState.Off)
  53 + } else {
  54 + EmptyComponent({ emptyHeight: 100 })
  55 + }
  56 + }
  57 +
  58 + /**
  59 + * 组件item
  60 + * @param programmeBean
  61 + * @param index
  62 + */
  63 + @Builder
  64 + buildItemView(item: ContentDTO, index: number) {
  65 + if (this.compStyle == CompStyle.Single_Column_01) {
  66 + SingleColumn01CardView({
  67 + item: item,
  68 + index: index
  69 + })
  70 + } else if (this.compStyle == CompStyle.Single_Column_02) {
  71 + SingleColumn02CardView({
  72 + item: item,
  73 + index: index
  74 + })
  75 + // } else if (this.compStyle == CompStyle.Single_Column_03) {
  76 + // SingleColumn03CardView({
  77 + // item: item,
  78 + // index: index
  79 + // })
  80 + } else {
  81 + Text("尚未实现");
  82 + }
  83 + }
  84 +}
@@ -16,8 +16,9 @@ export class CompUtils { @@ -16,8 +16,9 @@ export class CompUtils {
16 /** 16 /**
17 * The max lines. 17 * The max lines.
18 */ 18 */
19 - public static readonly MAX_LINES_ONE: number = 1;  
20 - public static readonly MAX_LINES_TWO: number = 2; 19 + public static readonly MAX_LINES_1: number = 1;
  20 + public static readonly MAX_LINES_2: number = 2;
  21 + public static readonly MAX_LINES_3: number = 3;
21 22
22 /** 23 /**
23 * 获取Label标题 24 * 获取Label标题
@@ -9,8 +9,16 @@ @@ -9,8 +9,16 @@
9 "value": "#333333" 9 "value": "#333333"
10 }, 10 },
11 { 11 {
  12 + "name": "color_666666",
  13 + "value": "#666666"
  14 + },
  15 + {
12 "name": "color_999999", 16 "name": "color_999999",
13 "value": "#999999" 17 "value": "#999999"
  18 + },
  19 + {
  20 + "name": "color_FE4B05",
  21 + "value": "#FE4B05"
14 } 22 }
15 ] 23 ]
16 } 24 }
1 { 1 {
2 "float": [ 2 "float": [
3 { 3 {
  4 + "name": "font_size_10",
  5 + "value": "10fp"
  6 + },
  7 + {
  8 + "name": "font_size_11",
  9 + "value": "11fp"
  10 + },
  11 + {
  12 + "name": "font_size_12",
  13 + "value": "11fp"
  14 + },
  15 + {
  16 + "name": "font_size_14",
  17 + "value": "14fp"
  18 + },
  19 + {
  20 + "name": "font_size_16",
  21 + "value": "16fp"
  22 + },
  23 + {
4 "name": "normal_text_size", 24 "name": "normal_text_size",
5 "value": "16fp" 25 "value": "16fp"
6 }, 26 },
7 { 27 {
  28 + "name": "font_size_24",
  29 + "value": "24fp"
  30 + },
  31 +
  32 + {
8 "name": "main_margin", 33 "name": "main_margin",
9 "value": "14vp" 34 "value": "14vp"
10 }, 35 },
11 { 36 {
  37 + "name": "margin_8",
  38 + "value": "8vp"
  39 + },
  40 + {
12 "name": "label_margin_top", 41 "name": "label_margin_top",
13 "value": "10vp" 42 "value": "10vp"
14 }, 43 },
15 { 44 {
  45 + "name": "margin_bottom_16",
  46 + "value": "16vp"
  47 + },
  48 + {
16 "name": "label_margin_bottom", 49 "name": "label_margin_bottom",
17 "value": "8vp" 50 "value": "8vp"
18 }, 51 },
@@ -29,16 +62,12 @@ @@ -29,16 +62,12 @@
29 "value": "88vp" 62 "value": "88vp"
30 }, 63 },
31 { 64 {
32 - "name": "font_size_14",  
33 - "value": "14fp"  
34 - },  
35 - {  
36 - "name": "font_size_10",  
37 - "value": "10fp"  
38 - },  
39 - {  
40 "name": "image_border_radius", 65 "name": "image_border_radius",
41 "value": "8vp" 66 "value": "8vp"
  67 + },
  68 + {
  69 + "name": "border_radius_6",
  70 + "value": "6vp"
42 } 71 }
43 ] 72 ]
44 } 73 }