HarmonyOS 鸿蒙Next 使用 Scroll 及其 nested 属性,实现一个有 header,body 为 Tabs,Tabcontent 里面为 List
HarmonyOS 鸿蒙Next 使用 Scroll 及其 nested 属性,实现一个有 header,body 为 Tabs,Tabcontent 里面为 List
更多关于HarmonyOS 鸿蒙Next 使用 Scroll 及其 nested 属性,实现一个有 header,body 为 Tabs,Tabcontent 里面为 List的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
文档: Refresh-滚动与滑动-ArkTS组件-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者 (huawei.com)
参考demo:
import { PullToRefresh, PullToRefreshConfigurator } from '[@ohos](/user/ohos)/pulltorefresh'
[@Entry](/user/Entry)
[@Component](/user/Component)
struct PullRefreshPage {
[@State](/user/State) currentIndex: number = 0
private dataNumbers: string[] = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
private tabList2Numbers: string[] = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'];
[@State](/user/State) data: string[] = [];
[@State](/user/State) tabList2: string[] = [];
private scroller: Scroller = new Scroller();
tabController: TabsController = new TabsController()
private refreshConfigurator: PullToRefreshConfigurator = new PullToRefreshConfigurator();
[@State](/user/State) isRefreshing: boolean = false
[@State](/user/State) isLoading: boolean = false
aboutToAppear() {
this.refreshConfigurator.setHasRefresh(false)
for (let i = 0; i < 20; i++) {
this.data.push(`列表item${i}`)
this.tabList2.push(`tab2_item${i}`)
}
}
[@Builder](/user/Builder)
customRefreshComponent() {
Stack() {
Row() {
LoadingProgress().height(32)
if (this.isLoading) {
Text("正在刷新").fontSize(16).margin({left:20})
}
}
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Center)
}.width("100%").align(Alignment.Center)
}
build() {
Refresh({ refreshing: $$this.isRefreshing, builder:this.customRefreshComponent()}) {
Scroll() {
Column(){
Text("Header")
.width("100%")
.height(140)
.backgroundColor('#0080DC')
.textAlign(TextAlign.Center)
Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.tabController }) {
TabContent() {
this.listBuilder()
}.tabBar(this.TabBuilder('TabItem_1', 0))
TabContent() {
Column(){
this.list2Builder()
}.width('100%').height('100%').backgroundColor(Color.Pink)
}.tabBar(this.TabBuilder('TabItem_2', 1))
}
.height('100%')
.vertical(false)
.onChange((index: number) => {
this.currentIndex = index
})
}.width("100%")
}
.edgeEffect(EdgeEffect.None)
.backgroundColor('#DCDCDC')
.scrollBar(BarState.Off)
.width('100%')
.height('100%')
}
.onRefreshing(() => {
this.isLoading = true
setTimeout(() => {
this.isRefreshing = false
this.isLoading = false
this.data = this.dataNumbers;
this.tabList2 = this.tabList2Numbers
}, 2000)
})
.backgroundColor(0x89CFF0)
}
[@Builder](/user/Builder) TabBuilder(label: string, index: number) {
Column() {
Text(label)
.fontSize(16)
.lineHeight(22)
.margin({ top: 6, bottom: 6 })
Divider()
.strokeWidth(2)
.width(60)
.color('#007DFF')
.opacity(this.currentIndex === index ? 1 : 0)
}.width('100%')
}
[@Builder](/user/Builder)
listBuilder() {
PullToRefresh({
// 必传项,列表组件所绑定的数据
data: $data,
// 必传项,需绑定传入主体布局内的列表或宫格组件
scroller: this.scroller,
// 必传项,自定义主体布局,内部有列表或宫格组件
customList: () => {
// 一个用[@Builder](/user/Builder)修饰过的UI方法
this.getList1View()
},
refreshConfigurator: this.refreshConfigurator,
// 可选项,上拉加载更多回调
onLoadMore: () => {
return new Promise<string>((resolve, reject) => {
// 模拟网络请求操作,请求网络2秒后得到数据,通知组件,变更列表数据
setTimeout(() => {
resolve('');
this.data.push("tab1增加的条目" + this.data.length)
}, 2000);
});
},
customLoad: null,
customRefresh: null,
})
}
[@Builder](/user/Builder)
list2Builder() {
PullToRefresh({
// 必传项,列表组件所绑定的数据
data: $tabList2,
// 必传项,需绑定传入主体布局内的列表或宫格组件
scroller: this.scroller,
// 必传项,自定义主体布局,内部有列表或宫格组件
customList: () => {
this.getList2View()
},
refreshConfigurator: this.refreshConfigurator,
// 可选项,上拉加载更多回调
onLoadMore: () => {
return new Promise<string>((resolve, reject) => {
// 模拟网络请求操作,请求网络2秒后得到数据,通知组件,变更列表数据
setTimeout(() => {
resolve('');
this.tabList2.push("tab2增加的条目" + this.tabList2.length)
}, 2000);
});
},
customLoad: null,
customRefresh: null,
})
}
[@Builder](/user/Builder)
private getList1View() {
List({ space: 10, scroller: this.scroller }) {
ForEach(this.data, (item: number) => {
ListItem() {
Text("item" + item).fontSize(16)
}
.backgroundColor(Color.White)
.height(70)
.width("100%")
.borderRadius(10)
}, (item: string) => item)
}.width("100%")
.height('100%')
.edgeEffect(EdgeEffect.None)
.divider({ strokeWidth: 1, color: 0x222222 })
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.SELF_FIRST
})
}
[@Builder](/user/Builder)
private getList2View() {
List({ space: 10, scroller: this.scroller }) {
ForEach(this.tabList2, (item: number) => {
ListItem() {
Text("item" + item).fontSize(16)
}
.backgroundColor(Color.White)
.height(70)
.width("100%")
.borderRadius(10)
}, (item: string) => item)
}.width("100%")
.height('100%')
.edgeEffect(EdgeEffect.None)
.divider({ strokeWidth: 1, color: 0x222222 })
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.SELF_FIRST
})
}
}
更多关于HarmonyOS 鸿蒙Next 使用 Scroll 及其 nested 属性,实现一个有 header,body 为 Tabs,Tabcontent 里面为 List的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next系统中,使用Scroll组件及其nested属性可以实现一个带有header、body为Tabs、TabContent里面为List的布局。以下是一个简要实现思路:
-
布局结构:
- 外层使用
Scroll
组件,设置nested
属性为true
以允许嵌套滚动。 Scroll
组件内首先放置一个header
,可以是任何自定义组件。- 接着是
Tabs
组件作为body
,设置相应的Tab项。 - 每个Tab项的内容为
List
组件,用于展示列表数据。
- 外层使用
-
实现细节:
- 确保
Scroll
组件的nested
属性为true
,以允许List
组件在Tabs
内部独立滚动。 - 为
Tabs
组件设置onTabSelected
事件监听器,以处理Tab切换逻辑。 - 每个Tab对应的
List
组件需要独立管理其数据源和滚动状态。
- 确保
-
注意事项:
- 在处理嵌套滚动时,注意滚动事件的传递和拦截,避免滚动冲突。
- 确保
Tabs
和List
组件的布局参数正确,避免布局错乱。
通过上述步骤,你可以在HarmonyOS鸿蒙Next系统中实现一个带有header、body为Tabs、TabContent里面为List的复杂布局。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html