HarmonyOS App首页滑动冲突问题(布局层级复杂)

1、demo如下(根据App首页抽出的demo),demo需依赖下拉刷新库"@ohos/pulltorefresh": "2.0.5",才能运行

2、期望效果,大致文字描述:在页面任何位置均可上拉及下拉滑动,整个的滑动效果为,上拉滑到tab栏置顶后,tab吸顶,之后精选内容列表响应滑动事件,下拉滑动则是待精选内容列表滑动到顶部后,则为父List响应滑动事件,出现十宫格。

3、目前存在的问题:1)十宫格区域无法上下滑动,与父List滑动有冲突 2)精选tab列表区域上下滑动,无法与父List联动

demo如下;

import { PullToRefresh, PullToRefreshConfigurator } from '@ohos/pulltorefresh';

@Entry
@Component
struct HomePageDemo {
  gridArray: string[] = ['grid1', 'grid2', 'grid3', 'grid4', 'grid5', 'grid6', 'grid7', 'grid8', 'grid9', 'grid10']
  tabArray: string[] = ['精选', '快讯']
  listArray: string[] =
    ['list1', 'list2', 'list3', 'list4', 'list5', 'list6', 'list7', 'list8', 'list9', 'list10', 'list11', 'list12',
      'list13', 'list14', 'list15', 'list16', 'list17', 'list18', 'list19', 'list20']
  private swiperController: SwiperController = new SwiperController()
  private scroller: Scroller = new Scroller()
  @State swiperIndex: number = 0
  @State listData: string[] = this.listArray

  aboutToAppear(): void {
  }

  build() {
    Column() {
      Search().width('100%').height(40)
      Stack() {
        this.HomeView()
      }
      .width('100%')
    }
  }

  @Builder
  HomeView() {
    List() {
      //十宫格
      ListItem() {
        Column() {
          this.HomeGridView()
          Blank().size({ width: '100%', height: 12 })
        }.width('100%')
      }

      //2个Tab,通过tabbuilder+swiper实现
      ListItemGroup({ header: this.ListHeader() }) {
        ListItem() {
          Swiper(this.swiperController) {
            ForEach(this.tabArray, (item: string, index: number) => {
              if (index == 0) {
                // 精选
                this.HomeRecommendView()
              } else if (index == 1) {
                // 快讯
                Blank().backgroundColor('#ff00ff').width('100%').height(2000)
              }
            }, (item: string) => item)
          }
          .loop(false)
          .size({ width: '100%' })
          .layoutWeight(1)
          .cachedCount(1)
          .indicator(false)
          .index(this.swiperIndex)
          .onChange((index: number) => {
            this.swiperIndex = index
          })
        }
      }
    }
    .scrollBar(BarState.Off)
    .sticky(StickyStyle.Header)
    .edgeEffect(EdgeEffect.None)
    .width('100%')
    .height('100%')
    .margin(40)
  }

  @Builder
  HomeGridView() {
    Row() {
      Grid() {
        ForEach(this.gridArray, (homeGridItem: string, index: number) => {
          // 展示前10个
          if (index < 10) {
            this.MyGridItem(homeGridItem)
          }
        })
      }
      .padding({ top: 16, bottom: 12 })
      .columnsTemplate("1fr 1fr 1fr 1fr 1fr") // 设置Grid为5列,并且均分
      .rowsGap(16) // 设置行间距
      .width('100%')
      .height(152)
    }
    .padding({ left: 16, right: 16 })
    .width('100%')
    .backgroundImageSize({ width: '100%' })
    .backgroundColor('#22333333')
  }

  @Builder
  MyGridItem(homeGridItem?: string) {
    GridItem() {
      Column() {
        Text(homeGridItem)
          .fontSize(13)
          .fontColor('#25262F')
          .fontWeight(400)
          .margin({ top: 6 })
          .width(70)
          .textAlign(TextAlign.Center)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
          .maxLines(1)
      }
    }
    .width('100%')
    .width(80)
    .height(55)
  }

  @Builder
  ListHeader() {
    Row() {
      ForEach(this.tabArray, (item: string, index) => {
        Row() {
          Stack() {
            Text(item)
              .size({ height: '100%' })
              .fontColor(this.swiperIndex === index ? '#FF0000' :
                '#000000')
              .fontSize(this.swiperIndex === index ? 22 : 16)
              .fontWeight(this.swiperIndex === index ? 500 : 400)
              .textAlign(TextAlign.Start)
          }
          .size({ width: 72, height: '100%' })
          .padding({ top: 12, bottom: 8 })
          .alignContent(Alignment.Bottom)
          .onClick(() => {
            this.swiperIndex = index
          })
        }
      }, (item: string) => item)
    }
    .size({ width: '100%', height: 48 })
    .justifyContent(FlexAlign.Start)
    .backgroundColor('#ffffff')
  }

  @Builder
  HomeRecommendView() {
    PullToRefresh({
      // 必传项,列表组件所绑定的数据
      data: $listData,
      // 必传项,需绑定传入主体布局内的滚动控制器
      scroller: this.scroller,
      // 必传项,自定义主体布局,内部有列表、宫格或滚动组件,需通过bind使this指向外层组件
      customList: () => this.ScrollLayout(),
      // 可选项,组件属性配置,具有默认值
      refreshConfigurator: new PullToRefreshConfigurator()
        .setHasRefresh(true)// 是否具有下拉刷新功能
        .setHasLoadMore(true)// 是否具有上拉加载功能
        .setMaxTranslate(80), // 可下拉上拉的最大距离
      // 可选项,下拉刷新回调
      onRefresh: () => {
        return new Promise<string>((resolve, reject) => {
          setTimeout(() => {
            this.listData = this.listArray
            resolve('刷新成功')
          }, 1000)
        })
      },
      onLoadMore: () => {
        return new Promise<string>((resolve, reject) => {
          setTimeout(() => {
            this.listData = this.listData.concat(this.listArray)
            resolve('刷新成功')
          }, 1000)
        })
      },
    }).size({ height: '100%', width: '100%' })
  }

  @Builder
  ScrollLayout() {
    List({ scroller: this.scroller }) {
      ForEach(this.listData, (pageData: string) => {
        ListItem() {
          Text(pageData).width('100%').height(50).backgroundColor('#00ffff')
        }
      }, (item: string, index: number) => item + index.toString())
    }
    .width('100%')
    .height('100%')
    .cachedCount(5) // cachedCount表示屏幕外List/Grid预加载item的个数。
    .scrollBar(BarState.Off)
    .listDirection(Axis.Vertical)
    .edgeEffect(EdgeEffect.None) // 必须设置列表为滑动到边缘无效果
    .padding({ left: 16, right: 16 })
  }
}
HarmonyOS
2025-01-09 14:50:03
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
zxjiu

方案:

在该demo的基础上

@State pullToRefreshConfigurator: PullToRefreshConfigurator = new PullToRefreshConfigurator()

aboutToAppear(): void {
  this.pullToRefreshConfigurator
  .setHasRefresh(false)// 是否具有下拉刷新功能
  .setHasLoadMore(true)// 是否具有上拉加载功能
  .setMaxTranslate(80) // 可下拉上拉的最大距离
}

@Builder
ScrollLayout() {
  List({ scroller: this.scroller }) {
    ForEach(this.listData, (pageData: string) => {
      ListItem() {
        Text(pageData).width('100%').height(50).backgroundColor('#00ffff')
      }
    }, (item: string, index: number) => item + index.toString())
  }
  .friction(2)
  // .contentStartOffset(this.isTriggeerDistance > 164 ? 0 : 1)
  .nestedScroll( { scrollForward: NestedScrollMode.PARENT_FIRST, scrollBackward:NestedScrollMode.SELF_FIRST})
  .width('100%')
  .height('100%')
  .cachedCount(5) // cachedCount表示屏幕外List/Grid预加载item的个数。
  .scrollBar(BarState.Off)
  .listDirection(Axis.Vertical)
  .edgeEffect(EdgeEffect.None) // 必须设置列表为滑动到边缘无效果
  .padding({ left: 16, right: 16 })
  .onWillScroll(() => {
    this.pullToRefreshConfigurator.setHasRefresh(true)
  })
}
分享
微博
QQ
微信
回复
2025-01-09 17:38:33
相关问题
HarmonyOS 滑动冲突问题
916浏览 • 1回复 待解决
HarmonyOS Refresh组件嵌套滑动冲突问题
1447浏览 • 1回复 待解决
HarmonyOS 滑动事件冲突
458浏览 • 1回复 待解决
HarmonyOS 首页金刚栏滑动demo
321浏览 • 1回复 待解决
HarmonyOS 父子组件滑动冲突
390浏览 • 1回复 待解决
HarmonyOS 首页滑动置顶组件吗?
408浏览 • 1回复 待解决
HarmonyOS list嵌套MapComponent滑动冲突
239浏览 • 1回复 待解决
滑动嵌套事件冲突处理
647浏览 • 0回复 待解决
HarmonyOS List+Swipe+web滑动冲突
367浏览 • 1回复 待解决
HarmonyOS Tabs和横向Scroll滑动冲突
409浏览 • 1回复 待解决
HarmonyOS 首页框架问题
757浏览 • 1回复 待解决
HarmonyOS Scroll中嵌套List滑动事件冲突
390浏览 • 1回复 待解决
HarmonyOS 关于CustomDialog显示层级问题
243浏览 • 1回复 待解决
Scroll内Flex加宽高与滑动冲突
2307浏览 • 1回复 待解决