Screenshot_2024-06-15T172422.png
数据模型
export class RoomListItemModel {
"id": number | undefined
"roomName": string | undefined
"imageUrl": string | undefined
"price": string | undefined
"labelList": string[] = []
}
import { RoomListItemModel } from './RoomListItemModel';
class BasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private originDataArray: RoomListItemModel[] = [];
public totalCount(): number {
return 0;
}
public getData(index: number): RoomListItemModel {
return this.originDataArray[index];
}
// 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
console.info('add listener');
this.listeners.push(listener);
}
}
// 该方法为框架侧调用,为对应的LazyForEach组件在数据源处去除listener监听
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
console.info('remove listener');
this.listeners.splice(pos, 1);
}
}
// 通知LazyForEach组件需要重载所有子组件
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
})
}
// 通知LazyForEach组件需要在index对应索引处添加子组件
notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
})
}
// 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件
notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}
// 通知LazyForEach组件需要在index对应索引处删除该子组件
notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}
// 通知LazyForEach组件将from索引和to索引处的子组件进行交换
notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMove(from, to);
})
}
}
export class RoomListDataSource extends BasicDataSource {
private dataArray: RoomListItemModel[] = [];
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): RoomListItemModel {
return this.dataArray[index];
}
public addData(index: number, data: RoomListItemModel): void {
this.dataArray.splice(index, 0, data);
this.notifyDataAdd(index);
}
public pushData(data: RoomListItemModel): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
}
viewModel
import requestModelAxios from '../../../model/RequestModelAxios'
import { RoomListItemModel } from './RoomListItemModel'
export class HotelRoomListViewModel {
pqgeNo:number = 1
getRoomList():Promise<RoomListItemModel[]> {
return new Promise((resolve,reject) => {
requestModelAxios.reqHotelRoomList()
.then(value => {
resolve(value)
})
.catch((error:string) => {
AlertDialog.show({message:error})
})
})
}
}
const roomListViewModel = new HotelRoomListViewModel()
export default roomListViewModel as HotelRoomListViewModel
主界面
import { Constants } from '../../../common/Constants';
import { RoomListItemModel } from '../model/RoomListItemModel'
import roomListViewModel from '../model/HotelRoomListViewModel'
import { Position, router } from '@kit.ArkUI';
import { RoomListDataSource } from '../model/RoomListDataSource';
@Entry
@Component
struct HotelRoomListPage {
@State message: string = 'Hello World';
@State roomList: RoomListItemModel[] = []
private roomListDataSource: RoomListDataSource = new RoomListDataSource()
isLoading: boolean = false
isMore: boolean = false
@State roomCount: number = 0
testLoadCount: number = 0
aboutToAppear(): void {
this.loadMoreList(false)
}
loadMoreList(isLoad: boolean) {
console.log('=============== orderList')
//测试数据
if (this.isLoading == false) {
this.testLoadCount = 0
}
roomListViewModel.getRoomList()
.then(value => {
console.log('========== room return')
this.roomList = this.roomList.concat(value)
value.flatMap((item) => {
this.roomListDataSource.pushData(item)
})
this.isLoading = false
this.isMore = false
this.testLoadCount++
if (value && value.length >= Constants.kPageSize10) {
this.isMore = true
if (this.testLoadCount > 3) {
this.isMore = false
}
}
})
}
jumpRoomDetail(model:RoomListItemModel) {
router.pushUrl({url:'pages/home/ctrl/RoomDetailPage',params:model})
}
@Builder
headeCountView() {
Row() {
Text('房间数量')
.fontSize(16)
.fontColor(Constants.COLOR_666666)
Row() {
Button() {
Image($r('app.media.delete_gray_mark'))
}
.buttonStyle(ButtonStyleMode.TEXTUAL)
.margin({ right: 4 })
.width(30)
.height(30)
.borderColor(Color.Gray)
.borderRadius(15)
.borderWidth(0.5)
TextInput({text:'1'})
.type(InputType.Number)
.textAlign(TextAlign.Center)
.height(35)
.constraintSize({minWidth:35})
.backgroundColor(Constants.COLOR_F1F3F5)
.onChange((value: string) => {
console.info(value);
})
.onFocus(() => {
console.info('获取焦点');
})
.onSubmit((EnterKeyType) => {
console.info(EnterKeyType + '输入法回车键的类型值')
})
Button() {
Image($r('app.media.add_mark'))
.fillColor(Constants.COLOR_ffcc33)
}
.margin({ left: 4 })
.buttonStyle(ButtonStyleMode.TEXTUAL)
.borderColor(Color.Black)
.borderRadius(15)
.borderWidth(0.5)
.width(30)
.height(30)
}
.height('44')
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.End)
}
.height(44)
.width('100%')
.padding({ left: 12, right: 12 })
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.SpaceBetween)
.backgroundColor(Color.White)
}
@Builder
gridLabelView(labs: string[]) {
// GridRow({ columns: 4,direction: GridRowDirection.Row }) {
// ForEach(labs, (item: string, index) => {
// GridCol() {
// Row() {
// Text(item)
// }.height(20)
// }
// .backgroundColor(Constants.RandomColor())
// })
// }
// .width('100%')
Flex({justifyContent: FlexAlign.Start,wrap: FlexWrap.Wrap,alignContent: FlexAlign.SpaceEvenly}){
ForEach(labs,(labContent:string)=>{
Text(labContent)
.flexBasis('auto')
.fontSize(12)
.height(20)
.padding({left:3,right:3})
.backgroundColor(Constants.COLOR_F1F3F5)
.borderWidth(0.5)
.borderColor(Constants.COLOR_666666)
.borderRadius(3)
.margin({right:4,top:4})
.opacity(0.5)
})
}
.width('100%')
}
@Builder
roomlistCell(item: RoomListItemModel) {
ListItem() {
Row() {
Row() {
Image(item.imageUrl)
.alt($r('app.media.placeholder'))
.width(80)
.height(80)
.borderRadius(8)
Column() {
Text(item.roomName)
.fontColor(Constants.COLOR_333333)
.fontSize(16)
.fontWeight(700)
.maxLines(2)
if (item.labelList.length > 0) {
this.gridLabelView(item.labelList)
}
}
.padding({left:8})
.width('68%')
.alignItems(HorizontalAlign.Start)
.justifyContent(FlexAlign.Center)
}
// .height('100%')
.layoutWeight(7)
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Start)
//.padding({left:8,right:8})
Column(){
Image($r('app.media.arrow_right_new'))
.size({width:12,height:12})
Text(`¥${item.price}起`)
.fontColor(Constants.COLOR_ffcc33)
.fontSize(14)
.textAlign(TextAlign.End)
.margin({top:8})
}
.height('100%')
.layoutWeight(3)
.alignItems(HorizontalAlign.End)
.justifyContent(FlexAlign.End)
}
// .height(80)
.width('100%')
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.SpaceBetween)
}
.width('100%')
.padding(8)
.height(96)
.borderRadius(8)
.backgroundColor(Color.White)
.onClick(()=>{
this.jumpRoomDetail(item)
})
}
@Builder
listView() {
List({ space: 10 }) {
LazyForEach(this.roomListDataSource, (item: RoomListItemModel, index) => {
this.roomlistCell(item)
}, (item: string) => item)
}
.cachedCount(5)
.position({ x: 0, y: 44 })
.padding(12)
.width('100%')
.height('100%')
.backgroundColor(Constants.COLOR_PAGE_BGC)
.onReachEnd(() => {
if (!this.isLoading && this.isMore) {
this.isLoading = true
roomListViewModel.pqgeNo++
this.loadMoreList(true)
}
})
}
build() {
Stack() {
this.headeCountView()
this.listView()
}
// .size({width:'100%',height:'100'})
.alignContent(Alignment.TopStart)
.width('100%')
.height('100%')
.backgroundColor(Constants.COLOR_PAGE_BGC)
}
}