HarmonyOS鸿蒙Next中Swiper滑动时有间隙

HarmonyOS鸿蒙Next中Swiper滑动时有间隙

已提供Demo,预期是:滑动swiper时,隐藏底部区域,web高度不变,web不要有闪动,swiper中间不要有间隙

swiper滑动时,我对底部区域进行隐藏,但不能使用Visibility.Hidden,因为会导致出现一个空白区域,目前对RelativeContainer的高度重新设置才不会导致滑动时web高度改变,但此时滑动swiper中间会出现一个空隙,看了一下Inspector发现SwiperItem高度没变,但RelativeContainer高度变了,如何解决

3 回复

【背景知识】

layoutWeight 是 HarmonyOS 布局中用于按比例分配空间的属性。它允许组件在父容器中根据权重值动态分配剩余空间,确保布局在不同屏幕尺寸下保持协调性。其权重值为正数(如 layoutWeight(1)),数值越大,组件占据的空间比例越高,layoutWeight 属性仅在 Row/Column/Flex 布局中生效。

【解决方案】

删除 SwiperItem 内 RelativeContainer 的高度判断和设置,删除 Web 的 layoutWeight 属性,增加 SwiperItem 的 layoutWeight 属性设置。修改后代码参考:

import { webview } from '@kit.ArkWeb';

@Component
struct Demo {
  private data: MyDataSource = new MyDataSource();
  @State swiperSliding: boolean = false;
  controller: webview.WebviewController = new webview.WebviewController();
  @State totalWidth: string = '100%'

  aboutToAppear(): void {
    for (let i = 1; i <= 3; i++) {
      this.data.pushData(i)
    }
  }

  build() {
    Swiper() {
      LazyForEach(this.data, () => {
        Column() {
          SwiperItem({
            swiperSliding: this.swiperSliding
          })
            .layoutWeight(this.swiperSliding ? 1 : 0)
          Text('你好')
            .width('100%')
            .backgroundColor(Color.Black)
        }
      })
    }
    .backgroundColor('#F5F6FA')
    .loop(false)
    .indicator(false)
    .vertical(true)
    .cachedCount(2)
    .effectMode(EdgeEffect.None)
    .onGestureSwipe((index: number, extraInfo: SwiperAnimationEvent) => {
      this.swiperSliding = true
    })
    .onAnimationEnd(() => {
      this.swiperSliding = false
    })
  }
}

@Component
struct SwiperItem {
  controller: webview.WebviewController = new webview.WebviewController();
  url: string = 'https://www.sina.cn'
  @Prop swiperSliding: boolean
  build() {
    RelativeContainer() {
      Text('顶Bar')
        .height(30)
        .width('100%')
        .backgroundColor(Color.Blue)
        .alignRules({
          top: { anchor: '__container__', align: VerticalAlign.Top },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .id('topBar')
      Text('底bar')
        .height(60)
        .width('100%')
        .backgroundColor(Color.Green)
        .visibility(this.swiperSliding ? Visibility.None : Visibility.Visible)
        .id('bottomBar')
        .alignRules({
          bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
      Web({ controller: this.controller, src: this.url })
        .alignRules({
          top: { anchor: 'topBar', align: VerticalAlign.Bottom },
          bottom: { anchor: 'bottomBar', align: VerticalAlign.Top }
        })
    }
  }
}

更多关于HarmonyOS鸿蒙Next中Swiper滑动时有间隙的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


鸿蒙Next中Swiper滑动出现间隙通常与布局参数或样式设置有关。检查Swiper组件的以下配置:

  1. 确认itemWidth是否设置为100%或匹配父容器宽度
  2. 检查margin/padding是否为0
  3. 设置clip属性为true避免子元素溢出
  4. 确保loop模式下前后补白项设置正确
  5. 检查是否因动态加载导致布局计算延迟

可通过设置Swiper的cachedCount预加载相邻项来改善滑动连续性。若使用自定义指示器,需同步调整其位置参数。

根据描述,Swiper滑动出现间隙的问题主要与RelativeContainer高度变化有关。建议尝试以下解决方案:

  1. 使用布局约束确保SwiperItem和RelativeContainer高度一致:
Swiper() {
  // Swiper内容
}
.height('100%')  // 确保Swiper填满父容器
  1. 对于底部区域隐藏问题,可以尝试使用translateY动画替代Visibility.Hidden:
RelativeContainer() {
  // 底部区域
}
.transition({ type: TransitionType.All, scale: { x: 1, y: 1 } })
.animate({
  duration: 300,
  curve: Curve.EaseOut,
  onFinish: () => {
    // 动画完成回调
  }
})
  1. 检查父容器是否设置了固定高度,建议使用百分比或明确的高度值:
Column() {
  Swiper() {
    // 内容
  }
  .layoutWeight(1)  // 确保Swiper占据剩余空间

  // 底部区域
}
.height('100%')
  1. 如果问题仍然存在,可以尝试在Swiper滑动事件中动态调整RelativeContainer的约束条件,而不是直接修改高度。
回到顶部