HarmonyOS鸿蒙Next中实现自定义Slider气泡

HarmonyOS鸿蒙Next中实现自定义Slider气泡

const BLOCK_DEFAULT_BORDER_WIDTH = 4;
@Entry
@Component
struct Test240816180043025 {
  @State isTipShow: boolean = false;
  @State tipsOffset: number = 0;
  private slideWidth: number = 300;
  private blockSize: number = 20;
  private tipWidth: number = 40;
  private hideTipTask?: number;

  private showTip(value: number) {
    this.isTipShow = true
    let percent = Number((value / 100).toFixed(2));
    this.tipsOffset = (this.slideWidth - this.blockSize - BLOCK_DEFAULT_BORDER_WIDTH * 2) * percent -
      (this.tipWidth / 2 - (this.blockSize / 2 + BLOCK_DEFAULT_BORDER_WIDTH));
    console.log("tipsOffset:" + this.tipsOffset)
  }

  private hideTip() {
    clearTimeout(this.hideTipTask)
    this.hideTipTask = setTimeout(() => {
      this.isTipShow = false
      this.tipsOffset = 0;
    }, 500)
  }

  build() {
    Column() {
      if (this.isTipShow) {
        Text(Number((this.tipsOffset + 6) / (this.slideWidth - this.tipWidth + 6 * 2) * 100).toFixed(0) + '%')
          .fontSize(12)
          .offset({ x: this.tipsOffset })
          .fontColor(Color.Black)
          .height(10)
          .padding({left:10})
          .borderRadius(5)
          .hitTestBehavior(HitTestMode.Transparent)
      } else {
        Text('')
          .fontSize(12)
          .height(10)
          .offset({ x: this.tipsOffset })
          .fontColor(Color.Black)
          .borderRadius(5)
          .hitTestBehavior(HitTestMode.Transparent)
      }
      Slider({ direction: Axis.Horizontal, })
        .width(this.slideWidth)
        .selectedColor(Color.Green)
        .trackColor('#5a5a5a')
        .trackThickness(10)
        .blockSize({ width: this.blockSize, height: this.blockSize })
        .selectedColor('#FF6103')
        .onAppear(() => {
          this.showTip(0);
        })
        .onChange((value: number, mode: SliderChangeMode) => {
          switch (mode) {
            case SliderChangeMode.Moving:
            case SliderChangeMode.Click:
              this.showTip(value);
              break;
            case SliderChangeMode.End:
              this.hideTip();
              break;
          }
        })

    }.alignItems(HorizontalAlign.Start).padding(20).width('100%').backgroundColor(Color.Blue)
  }

更多关于HarmonyOS鸿蒙Next中实现自定义Slider气泡的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

你好,没有明白你当前是遇到了什么样的问题,可以描述下你的问题,或者需求么

更多关于HarmonyOS鸿蒙Next中实现自定义Slider气泡的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中实现自定义Slider气泡,可以通过Slider组件的onChange事件监听滑动值变化,并使用Text组件动态显示气泡内容。通过Stack布局将Text组件定位在Slider上方,结合Position属性调整气泡位置。使用State管理滑动值,确保气泡内容实时更新。

在HarmonyOS Next中实现自定义Slider气泡,你的代码思路基本正确,但可以优化几个点:

  1. 气泡定位计算可以简化,直接基于Slider的value值计算百分比位置即可,不需要复杂的offset计算

  2. 建议使用Stack布局替代if-else条件渲染,这样气泡位置会更稳定

  3. 气泡样式建议添加背景色和阴影提升视觉效果

优化后的关键代码片段:

Stack() {
  Slider({ direction: Axis.Horizontal })
    .width(this.slideWidth)
    .onChange((value: number) => {
      this.currentValue = value;
    })

  Text(`${this.currentValue}%`)
    .width(this.tipWidth)
    .textAlign(TextAlign.Center)
    .backgroundColor('#FFFFFF')
    .borderRadius(10)
    .shadow({radius: 2})
    .offset({
      x: (this.slideWidth - this.tipWidth) * (this.currentValue/100)
    })
}

主要改进:

  • 使用Stack确保气泡始终在Slider上方
  • 直接基于value值计算气泡位置
  • 添加了背景色和阴影提升视觉效果
  • 移除了不必要的hideTip逻辑,保持气泡常显

这种实现方式更简洁,且能保证气泡始终跟随滑块位置。

回到顶部