鸿蒙 Next:房间列表

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)
  }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容