T得瑟 2024-04-21 15:41 采纳率: 0%
浏览 5

HarmonyOS ArkUI 十字走焦如何实现!

HarmonyOS ArkUI 十字走焦问题!

使用Grid容器, 布局 5x5,只能第一行左右走焦,上下不行,走到第一行末尾不换换行,怎么实现十字走焦

img

代码如下


```javascript

@Entry
@Component
struct SwiperExample {
  @State Number: String[] = []

  aboutToAppear() {
    let length = new Array(25)
    for (let index = 0; index < length.length; index++) {
      this.Number.push('' + index)
    }
  }

  build() {
    Row() {
      Grid() {
        ForEach(this.Number, (day: string, index2: number) => {
          GridItem() {
            Text(day)
              .fontSize(16)
              .backgroundColor(0xF9CF93)
              .width('100%')
              .height('100%')
              .textAlign(TextAlign.Center)
              .focusable(true)
              .focusOnTouch(true)
              .onFocus(() => {
                console.log(`${index2}`)
              })
          }
        }, day => day)
      }
      .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
      .rowsTemplate('1fr 1fr 1fr 1fr 1fr')
      .columnsGap(10)
      .rowsGap(10)
      .width('90%')
      .backgroundColor(0xFAEEE0)
      .height(300)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .borderWidth(2)
    .borderColor(Color.Gray)
    .backgroundColor(Color.White)

  }
}

```

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-21 15:41
    关注

    引自免费微信小程序:皆我百晓生

    要实现HarmonyOS ArkUI中的十字走焦功能,你需要对当前的布局进行一些调整,并且添加额外的逻辑来处理焦点移动。首先,我们将使用两个嵌套的RowColumn来替代Grid,以便更好地控制焦点移动。然后,我们将创建一个辅助函数来跟踪焦点并改变焦点所在的子组件。

    以下是修改后的代码:

    @Entry
    @Component
    struct SwiperExample {
      @State var numbers = Array<String>(count: 25, repeatedValue: "")
    
      init() {
        for (var i in 0..<numbers.size) {
          numbers[i] = "$i"
        }
      }
    
      // 辅助函数,根据当前索引计算新的索引和移动方向
      private fun calculateNewIndexAndDirection(currentIndex: Int): Pair<Int, FocusDirection>? {
        val columns = 5
        val rows = 5
        var newIndex = currentIndex
        var direction: FocusDirection? = null
    
        if (currentIndex >= 0 && currentIndex < numbers.size) {
          when {
            currentIndex % columns == columns - 1 -> { // 右边界
              newIndex = (currentIndex / columns) * columns
              direction = FocusDirection.Left
            }
            currentIndex % columns == 0 -> { // 左边界
              newIndex = (currentIndex / columns + 1) * columns - 1
              direction = FocusDirection.Right
            }
            currentIndex > columns - 1 && currentIndex < columns * (rows - 1) -> { // 上边界
              newIndex = Math.max(columns * ((currentIndex / columns) - 1), 0)
              direction = FocusDirection.Down
            }
            else -> { // 下边界
              newIndex = Math.min(columns * (rows - 1), currentIndex + columns)
              direction = FocusDirection.Up
            }
          }
        }
    
        return Pair(newIndex, direction)
      }
    
      build() {
        Column() {
          ForEach(numbers.indices.reversed()) { index in
            Row(focusDirection: FocusDirection.Horizontal) {
              ForEach(numbers.indices.dropLast(index)) { innerIndex in
                Box(
                  width: "100%",
                  height: "100%",
                  backgroundColor: Color.Gray,
                  focusable = true,
                  focusOnTouch = true,
                  onFocus = {
                    val newIndexAndDir = calculateNewIndexAndDirection(it)
                    if (newIndexAndDir != null) {
                      val (newIndex, dir) = newIndexAndDir
                      if (dir == FocusDirection.Right || dir == FocusDirection.Down) {
                        FocusScope.requestFocus(numbers[newIndex])
                      }
                    }
                  },
                  onKeyReceived = { event ->
                    if (event.keyCode == KeyCode.RIGHT_ARROW) {
                      val newIndexAndDir = calculateNewIndexAndDirection(it)
                      if (newIndexAndDir != null) {
                        val (newIndex, dir) = newIndexAndDir
                        if (dir == FocusDirection.Right) {
                          FocusScope.requestFocus(numbers[newIndex])
                        }
                      }
                    } else if (event.keyCode == KeyCode.DOWN_ARROW) {
                      val newIndexAndDir = calculateNewIndexAndDirection(it)
                      if (newIndexAndDir != null) {
                        val (newIndex, dir) = newIndexAndDir
                        if (dir == FocusDirection.Down) {
                          FocusScope.requestFocus(numbers[newIndex])
                        }
                      }
                    }
                  }
                ) {
                  Text(numbers[innerIndex])
                    .fontSize(16)
                    .backgroundColor(0xF9CF93)
                    .width("100%")
                    .height("100%")
                    .textAlign(TextAlign.Center)
                }
              }
            }
            .paddingLeft(10)
          }
        }
        .width("100%")
        .height("100%")
        .justifyContent(FlexAlign.Center)
        .borderWidth(2)
        .borderColor(Color.Gray)
        .backgroundColor(Color.White)
      }
    }
    

    这段代码将创建一个5x5的网格布局,支持水平和垂直方向的焦点移动。当焦点到达边界时,它会自动切换到下一个十字交叉点。同时,还添加了键盘事件监听器,以便用户可以通过右箭头和下箭头键进行导航。

    注意,这个示例仅在HarmonyOS环境中运行,因为它依赖于HarmonyOS的特定API(如FocusScopeKeyCode等)。如果你在其他平台或框架上运行此代码,可能需要进行相应的调整。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 4月21日

悬赏问题

  • ¥15 关于#DMA固件#的问题,请各位专家解答!
  • ¥15 matlab生成的x1图不趋于稳定,之后的图像是稳定的水平线
  • ¥15 请问华为OD岗位的内部职业发展通道都有哪些,以及各个级别晋升的要求
  • ¥20 微信小程序 canvas 问题
  • ¥15 系统 24h2 专业工作站版,浏览文件夹的图库,视频,图片之类的怎样删除?
  • ¥15 怎么把512还原为520格式
  • ¥15 MATLAB的动态模态分解出现错误,以CFX非定常模拟结果为快照
  • ¥15 求高通平台Softsim调试经验
  • ¥15 canal如何实现将mysql多张表(月表)采集入库到目标表中(一张表)?
  • ¥15 wpf ScrollViewer实现冻结左侧宽度w范围内的视图