HarmonyOS 鸿蒙Next求助:有没类似影院选座位购票的示例代码

发布于 1周前 作者 yibo5220 来自 鸿蒙OS

HarmonyOS 鸿蒙Next求助:有没类似影院选座位购票的示例代码

需要开发一个类似影院购票选座的页面,web/安卓一般都是用Canvas绘图实现的,但是代码没法直接迁移到鸿蒙上使用,问下有没有可参考的鸿蒙代码

4 回复
import { promptAction } from '@kit.ArkUI';

@Entry
@Component
struct NiuTestPage {

  @State seats: number[][] = []
  @State lines: number = 7
  @State arranges: number = 10
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context2d: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);


  build() {
    Column()  {
        Canvas(this.context2d)
          .onReady(() => {
            this.initSeats()
          })
          .gesture(
            // 绑定count为1的TapGesture
            TapGesture({ count: 1 })
              .onAction((event: GestureEvent) => {
                if(event){
                  this.handleClick(event)
                }
              }))
          .backgroundColor(Color.Pink)
          .width('100%')
          .height('100%')
    }
    .width('100%')
    .height('100%');
  }

  // 初始化座位
  private initSeats() {
    for (let x: number = 0; x < this.lines; x += 1) {
      this.seats[x] = []
      for (let y: number = 0; y < this.arranges; y += 1) {
        this.seats[x][y] = 0
        this.drawSeat(x * 40 + 50, y * 40 + 50, 0)
      }
    }
  }

  private drawSeat(x: number, y:number, state:number) {
    switch (state) {
      case 0:
        // 可选座位
        this.context2d.fillStyle = '#fff5f3f3';
        break;
      case 1:
        // 已选座位
        this.context2d.fillStyle = '#ffea7878';
        break;
      case 2:
        // 已售座位
        this.context2d.fillStyle = '#ff8f8b8b';
        break;
      default:
        // 其他座位
        this.context2d.fillStyle = '#ff161515';
        break;
    }
    this.context2d.fillRect(x, y, 30, 20)
  }

  private updateSeat(x: number, y: number) {
    if (this.seats[x][y] == 0) {
      this.seats[x][y] = 1
    } else if (this.seats[x][y] == 1) {
      this.seats[x][y] = 0
    }
    this.drawSeat(x * 40 + 50, y * 40 + 50, this.seats[x][y])
  }

  // 检查座位状态
  private checkSeat(x: number, y: number) {
    if (this.seats[x][y] == 2) {
      promptAction.showToast({message: '该座位已售出,请选择其他座位'});
      return false
    } else if (this.seats[x][y] == 1) {
      promptAction.showToast({message: '该座位已被选中,请选择其他座位'});
      return false
    }
    return true
  }

  // 统计已选座位数量和位置
  private countSelectedSeats() {
    let selectedSeats: number[][] = []
    let count = 0
    for (let x: number = 0; x < this.lines; x += 1) {
      for (let y: number = 0; y < this.arranges; y += 1) {
        if (this.seats[x][y] == 1) {
          selectedSeats.push([x, y])
          count++
        }
      }
    }
    return [count, selectedSeats]
  }

  // 处理点击事件
  private handleClick(event: GestureEvent) {
    let x = Math.floor((event.fingerList[0].localX - 50) / 40)
    let y = Math.floor((event.fingerList[0].localY - 50) / 40)

    if (x >= 0 && x < this.lines && y >= 0 && y < this.arranges) {
      if (this.checkSeat(x, y)) {
        this.updateSeat(x,y)
        let count = this.countSelectedSeats()[0]
        if (count > 0) {
          promptAction.showToast({message: '确认并支付(已选 ' + count +' 座位)'});
        }
      }
    }
  }
}
import SeatItem from './SeatItem'

@Entry @Component struct Index { @State services: Number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20]

build() { Row() { Column() { Text(‘选座Demo’).fontColor(Color.Red).height(60).fontWeight(FontWeight.Bold) Grid() { ForEach(this.services, (service: Number) => { GridItem() { SeatItem() } }, (service: Number) => JSON.stringify(service)) } .rowsGap(20) .columnsTemplate(‘1fr 1fr 1fr 1fr’) }.backgroundColor(Color.Black) } } } <button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

@Component
export default struct SeatItem {
@State isSelected: boolean = false;
@State itemBg: string = “#ff25b7b7”

build() { Column() {

}.height(<span class="hljs-number"><span class="hljs-number">50</span></span>)
.width(<span class="hljs-number"><span class="hljs-number">50</span></span>)
.onClick(() =&gt; {
  <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.isSelected = !<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.isSelected;
  <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.itemBg = <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.isSelected ? <span class="hljs-string"><span class="hljs-string">"#ffb72597"</span></span> : <span class="hljs-string"><span class="hljs-string">"#ff25b7b7"</span></span>;}).backgroundColor(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.itemBg)

} }<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

可以利用这种方式构建座位,在添加购票能力,Canvas绘图也可以进行鸿蒙适配

这个demo只是使用Grid布局排了一些格子 点击格子可以变换颜色 这个无法满足实际的影院选座的效果。有没有Canvas的实现的类似代码,

针对您提到的HarmonyOS(鸿蒙)Next系统中关于影院选座位购票的示例代码需求,以下是一个简要的代码框架说明,由于篇幅限制,仅提供核心逻辑:

在HarmonyOS开发中,您可以使用ArkUI(基于JS或eTS)或Java/Kotlin(针对原生应用)进行开发。以下是一个基于ArkUI (eTS) 的简化示例:

@Entry
@Component
struct SeatSelection {
    @State seats: Array<Array<string>> = generateSeatMap(10, 10, 'available');

    @Builder selectSeat(row: number, col: number) {
        if (this.seats[row][col] === 'available') {
            this.seats[row][col] = 'selected';
        }
    }

    function generateSeatMap(rows: number, cols: number, status: string): Array<Array<string>> {
        // 初始化座位图
        let map = [];
        for (let i = 0; i < rows; i++) {
            map[i] = [];
            for (let j = 0; j < cols; j++) {
                map[i][j] = status;
            }
        }
        return map;
    }

    // 渲染座位界面逻辑
}

上述代码生成了一个10x10的座位图,并提供了一个选择座位的功能。您可以根据实际需求进一步扩展,包括购票逻辑、UI美化等。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部