소스 검색

封装进度条组件

chenritian 3 주 전
부모
커밋
a0954224dc

+ 2 - 0
commons/basic/Index.ets

@@ -1,3 +1,5 @@
+export { YtProgressComp } from './src/main/ets/components/generalComp/YtProgressComp'
+
 export { Pet } from './src/main/ets/rdb/tables/Pet'
 
 export { RDBMapper } from './src/main/ets/rdb/utils/RDBMapper'

+ 249 - 0
commons/basic/src/main/ets/components/generalComp/YtProgressComp.ets

@@ -0,0 +1,249 @@
+import { YTAvoid } from "../../utils/YTAvoid";
+import { yTRouter } from "../../utils/YTRouter";
+//等级参数接口
+export interface GradeParam{
+  point: number;
+  position: number;//1-10等份的位置
+  topImage?:ResourceStr
+  selectImage?:ResourceStr
+  unSelectImage?:ResourceStr
+}
+
+@Component
+export struct YtProgressComp {
+  @Link growPoint: number
+  @State lastClickTime: number = 0;
+  @State coolDown: boolean = false;
+  @State isShowToast: boolean = false;
+  v0Point: GradeParam = {point:0,position:0,topImage:$r('app.media.icon_crown_gold'),selectImage:$r('app.media.icon_grow_yes'),unSelectImage:$r('app.media.icon_grow_no')};
+  v1Point: GradeParam = {point:70,position:3};
+  v2Point: GradeParam = {point:300,position:10};
+  @State private  v1Area:Position = {x:0,y:0}
+  @State private  v2Area:Position = {x:0,y:0}
+  currentPointImage: ResourceStr = $r('app.media.icon_crown_red');
+  getProgressWidth() {
+    // 总长度定义为299
+    const totalLength = 299;
+
+    // 各关键点的位置
+    const firstPointRight = 23; // 第一个点右侧位置
+    const secondPointLeft = Number(this.v1Area.x); // 第二个点左侧位置
+    const secondPointRight = Number(this.v1Area.x)+23; // 第二个点右侧位置
+    const thirdPointLeft = Number(this.v2Area.x); // 第三个点左侧位置
+    let width = 0;
+
+    if (this.growPoint >= this.v2Point.point) {
+      // 成长值达到300及以上,进度条满格
+      width = totalLength;
+    } else if (this.growPoint >= this.v1Point.point) {
+      // 成长值在v1Point及以上,在第二点右侧至第三点左侧之间线性增长
+      const progressRatio = Math.min((this.growPoint - this.v1Point.point) / (this.v2Point.point - this.v1Point.point), 1);
+      width = secondPointRight + (thirdPointLeft - secondPointRight) * progressRatio;
+    } else {
+      // 成长值在(this.v1Point - 10)以下,在第一点右侧至第二点左侧之间线性增长
+      if (this.growPoint <= (this.v1Point.point - 10)) {
+        const progressRatio = Math.min(this.growPoint / (this.v1Point.point - 10), 1);
+        width = firstPointRight + (secondPointLeft - firstPointRight) * progressRatio;
+      } else {
+        // 特殊处理:当成长值在60-70之间时,保持在第二点左侧
+        width = secondPointLeft;
+      }
+    }
+
+    console.log(`进度值:${this.growPoint}, 进度宽度:${width}`);
+    return Math.min(width, totalLength);
+  }
+
+  getNeedGrow() {
+    let neededPoints = 0;
+    if (this.growPoint < this.v1Point.point) {
+      neededPoints = this.v1Point.point - this.growPoint;
+    } else if (this.growPoint < this.v2Point.point) {
+      neededPoints = this.v2Point.point - this.growPoint;
+    } else {
+      return 0;
+    }
+    return neededPoints;
+  }
+
+  build() {
+      Column() {
+        RelativeContainer() {
+          Image($r('app.media.bg_progress'))
+            .width(338)
+            .height(119)
+            .alignRules({
+              top: { anchor: '__container__', align: VerticalAlign.Top },
+              middle: { anchor: '__container__', align: HorizontalAlign.Center }
+            })
+
+
+          RelativeContainer() {
+            Row()
+              .width(253 + 46)
+              .height(16)
+              .borderRadius(8)
+              .border({
+                width: 1,
+                color: '#000'
+              })
+              .zIndex(2)
+              .alignRules({
+                center: { anchor: '__container__', align: VerticalAlign.Center },
+                left: { anchor: '__container__', align: HorizontalAlign.Start }
+              })
+            Row()
+              .width(this.getProgressWidth())//根据成长值改变
+              .height(16)
+              .borderRadius(8)
+              .border({
+                width: { right: 1 },
+                color: '#000'
+              })
+              .id('progress_width')
+              .zIndex(1)
+              .backgroundColor('#5491D5')
+              .alignRules({
+                center: { anchor: '__container__', align: VerticalAlign.Center },
+                left: { anchor: '__container__', align: HorizontalAlign.Start }
+              })
+
+            Image(this.growPoint > 0 ? this.v0Point.selectImage?this.v0Point.selectImage:$r('app.media.icon_grow_yes') :this.v0Point.selectImage?this.v0Point.selectImage: $r('app.media.icon_grow_no'))
+              .width(23)
+              .aspectRatio(1)
+              .id('first_progress')
+              .alignRules({
+                center: { anchor: '__container__', align: VerticalAlign.Center },
+                left: { anchor: '__container__', align: HorizontalAlign.Start },
+                right: { anchor: '__container__', align: HorizontalAlign.End },
+                bias: { horizontal: 0 / 10 }
+              })
+              .zIndex(3)
+
+            Image(this.v0Point.topImage?this.v0Point.topImage:$r('app.media.icon_crown_gold'))
+              .width(23)
+              .alignRules({
+                bottom: { anchor: 'first_progress', align: VerticalAlign.Top },
+                middle: { anchor: 'first_progress', align: HorizontalAlign.Center },
+              })
+              .id('icon_crown_gold')
+              .margin({ bottom: 3 })
+              .zIndex(3)
+
+            if (this.growPoint != this.v1Point.point && this.growPoint < this.v2Point.point) {
+              Image(this.currentPointImage)
+                .width(23)
+                .alignRules({
+                  bottom: { anchor: 'progress_width', align: VerticalAlign.Top },
+                  middle: { anchor: 'progress_width', align: HorizontalAlign.End },
+                })
+                .id('icon_crown_red')
+                .margin({ bottom: 2, right: 4 })
+                .zIndex(3)
+            }
+
+            Image(this.v1Point.topImage?this.v1Point.topImage:$r('app.media.icon_crown_blue'))
+              .width(23)
+              .alignRules({
+                bottom: { anchor: 'second_progress', align: VerticalAlign.Top },
+                middle: { anchor: 'second_progress', align: HorizontalAlign.Center },
+              })
+              .id('icon_crown_blue')
+              .margin({ bottom: 3 })
+              .zIndex(3)
+
+            Image(this.v2Point.topImage?this.v2Point.topImage:$r('app.media.icon_crown_yellow'))
+              .width(23)
+              .alignRules({
+                bottom: { anchor: 'third_progress', align: VerticalAlign.Top },
+                middle: { anchor: 'third_progress', align: HorizontalAlign.Center },
+              })
+              .id('icon_crown_yellow')
+              .margin({ bottom: 3 })
+              .zIndex(3)
+
+            Image(this.growPoint >= this.v1Point.point ? this.v1Point.selectImage?this.v1Point.selectImage:$r('app.media.icon_grow_yes') :  this.v1Point.selectImage?this.v1Point.selectImage:$r('app.media.icon_grow_no'))
+              .width(23)
+              .aspectRatio(1)
+              .id('second_progress')
+              .alignRules({
+                center: { anchor: '__container__', align: VerticalAlign.Center },
+                left: { anchor: '__container__', align: HorizontalAlign.Start },
+                right: { anchor: '__container__', align: HorizontalAlign.End },
+                bias: { horizontal: this.v1Point.position / 10 }
+              })
+              .zIndex(3)
+              .onAreaChange((_,newArea)=>{
+                console.log(`进度区域:${JSON.stringify(newArea)}`);
+                this.v1Area = newArea.position
+              })
+
+            Image(this.growPoint >= this.v2Point.point ? this.v2Point.selectImage?this.v2Point.selectImage:$r('app.media.icon_grow_yes') :  this.v2Point.selectImage?this.v2Point.selectImage:$r('app.media.icon_grow_no'))
+              .width(23)
+              .aspectRatio(1)
+              .id('third_progress')
+              .alignRules({
+                center: { anchor: '__container__', align: VerticalAlign.Center },
+                left: { anchor: '__container__', align: HorizontalAlign.Start },
+                right: { anchor: '__container__', align: HorizontalAlign.End },
+                bias: { horizontal: this.v2Point.position / 10 }
+              })
+              .zIndex(3)
+              .onAreaChange((_,newArea)=>{
+                console.log(`进度区域:${JSON.stringify(newArea)}`);
+                this.v2Area = newArea.position
+              })
+
+
+          }
+          .height(23)
+          .width(253 + 46)
+          .alignRules({
+            top: { anchor: '__container__', align: VerticalAlign.Top },
+            left: { anchor: '__container__', align: HorizontalAlign.Start }
+          })
+          .margin({
+            top: 23,
+            left: 19
+          })
+
+          Row({ space: 8 }) {
+            Column() {
+              Text('我的成长点')
+                .font({ size: 12, weight: FontWeight.Normal })
+                .fontColor('#000')
+              Text(this.growPoint.toString())
+                .font({ size: 24, weight: FontWeight.Bold })
+                .fontColor('#000')
+                .maxLines(1)
+                .textOverflow({ overflow: TextOverflow.MARQUEE })
+            }
+
+            Image($r('app.media.icon_right'))
+              .width(8)
+          }
+          .alignRules({
+            bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
+            left: { anchor: '__container__', align: HorizontalAlign.Start }
+          })
+          .margin({
+            left: 7, bottom: 6
+          })
+          .onClick(() => {
+            //todo 点击成长
+          })
+        }
+        .height(119)
+        .width(338)
+        .margin({
+          top: YTAvoid.getTop()
+        })
+        .onClick(() => {
+
+        })
+
+      }
+      .width('100%')
+      .id('bg_cat')
+  }
+}

BIN
commons/basic/src/main/resources/base/media/bg_cat_v1.png


BIN
commons/basic/src/main/resources/base/media/bg_cat_v2.png


BIN
commons/basic/src/main/resources/base/media/bg_cat_v3.png


BIN
commons/basic/src/main/resources/base/media/bg_progress.png


BIN
commons/basic/src/main/resources/base/media/bg_toast.png


BIN
commons/basic/src/main/resources/base/media/icon_crown_blue.png


BIN
commons/basic/src/main/resources/base/media/icon_crown_gold.png


BIN
commons/basic/src/main/resources/base/media/icon_crown_red.png


BIN
commons/basic/src/main/resources/base/media/icon_crown_yellow.png


BIN
commons/basic/src/main/resources/base/media/icon_grow_no.png


BIN
commons/basic/src/main/resources/base/media/icon_grow_yes.png


BIN
commons/basic/src/main/resources/base/media/icon_right.png


+ 28 - 1
features/feature/src/main/ets/view/MainView.ets

@@ -1,9 +1,12 @@
-import { BackgroundPageModifier, DateOption, YTAddressSelectorDialog, YTDateUtil, yTRouter } from 'basic'
+import { BackgroundPageModifier, DateOption, YTAddressSelectorDialog, YTDateUtil,
+  YtProgressComp,
+  yTRouter } from 'basic'
 import { UnitType } from 'basic/src/main/ets/datepicker/DatePickerEnums'
 import { promptAction } from '@kit.ArkUI'
 
 @Component
 export struct MainView {
+  @State point:number = 40
   build() {
     Column() {
       Text('打开日历')
@@ -40,9 +43,33 @@ export struct MainView {
         .onClick(()=>{
           yTRouter.pushPathByName('TestRouterPage',null)
         })
+
+      YtProgressComp({
+        growPoint:this.point,
+        v1Point:{
+          point:100,
+          position:4
+        },
+        v2Point:{
+          point:200,
+          position:10,
+          topImage:$r('app.media.app_icon'),
+        }
+      })
+      Row(){
+        Button('+10')
+          .onClick(()=>{
+            this.point += 10
+          })
+        Button('-10')
+          .onClick(()=>{
+            this.point -= 10
+          })
+      }
     }
     .attributeModifier(new BackgroundPageModifier(true))
 
+
   }
 }