You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Syncfusion Flutter DataGrid移动端键盘事件监听及单元格跳转异常

问题描述

我想在SfDataGrid编辑状态下跳转到同行的下一个单元格,参考官方单元格跳转示例后,自定义了EditorGridSelectionManager类,代码如下:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:logging/logging.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:flutter/foundation.dart';

class EditorGridSelectionManager extends RowSelectionManager {
  final DataGridController dataGridController;
  Logger _logger=Logger('EditorGridSelectionManager');
  
  EditorGridSelectionManager({this.dataGridController});
  
  @override
  void handleKeyEvent(RawKeyEvent keyEvent) async {
    if (keyEvent.logicalKey == LogicalKeyboardKey.tab) {
      WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
        dataGridController.beginEdit(dataGridController.currentCell);
      });
    }
    if(keyEvent.logicalKey == LogicalKeyboardKey.f2){
      WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
        dataGridController.beginEdit(dataGridController.currentCell);
      });
    }
    if(defaultTargetPlatform==TargetPlatform.android || defaultTargetPlatform==TargetPlatform.iOS){
      _logger.info('Estoy en Mobile');
      if(keyEvent.logicalKey == LogicalKeyboardKey.arrowDown){
        _logger.info('Presione Next');
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
          dataGridController.beginEdit(dataGridController.currentCell);
        });
      }
    }
    super.handleKeyEvent(keyEvent);
  }
}

同时在TextField中设置textInputAction为TextInputAction.next以启用移动端虚拟键盘的Next按钮,代码片段如下:

return TextField(
    controller: controller,
    onChanged: this.onValueChanged,
    onSubmitted: this.onSubmitted,
    maxLength: length,
    keyboardType: this.textInputType,
    textCapitalization: TextCapitalization.sentences,
    textInputAction: TextInputAction.next,
    inputFormatters: _buildInputFormatter(),
    focusNode: this._focusNode,
    decoration: InputDecoration(
      border: InputBorder.none,
      contentPadding: EdgeInsets.only(top: 14.0),
      errorText: snapshot.error,
      errorStyle: TextStyle(color: Colors.red, fontWeight: FontWeight.bold),
      //hintText: textHint!=null ? textHint : 'Inform '+label
    ),
);

我已按照示例要求在SfDataGrid中设置RowSelectionManager,且从DataSource返回编辑组件。目前Web端按下Tab键可正常跳转至下一个单元格编辑,但移动端按下虚拟键盘的Next键毫无反应,且似乎从未进入EditorGridSelectionManager的handleKeyEvent方法。请问哪里操作有误?


解决方案

核心问题原因

移动端虚拟键盘的Next按钮触发的是TextField的onSubmitted回调,而非RawKeyEvent,因此handleKeyEvent方法无法捕获该事件。Web端Tab键属于系统原生按键事件,能被handleKeyEvent处理,但移动端软键盘的操作逻辑完全不同。

具体修复步骤

  1. 在TextField的onSubmitted中实现跳转逻辑
    直接在TextField的提交回调里处理单元格跳转,替换原有的无效逻辑:

    return TextField(
        // 保留原有配置
        textInputAction: TextInputAction.next,
        onSubmitted: (_) {
            final currentCell = dataGridController.currentCell;
            if (currentCell != null) {
                // 计算同行下一个单元格的列索引
                final nextColumnIndex = currentCell.columnIndex + 1;
                // 检查列索引是否在有效范围内
                if (nextColumnIndex < dataGridController.columns.length) {
                    final nextCell = DataGridCellPosition(
                        rowIndex: currentCell.rowIndex,
                        columnIndex: nextColumnIndex,
                    );
                    // 切换到下一个单元格并进入编辑状态
                    dataGridController.currentCell = nextCell;
                    dataGridController.beginEdit(nextCell);
                } else {
                    // 可选:若当前是最后一列,跳转至下一行第一个单元格
                    final nextRowIndex = currentCell.rowIndex + 1;
                    if (nextRowIndex < dataGridController.dataSource.rows.length) {
                        final nextCell = DataGridCellPosition(
                            rowIndex: nextRowIndex,
                            columnIndex: 0,
                        );
                        dataGridController.currentCell = nextCell;
                        dataGridController.beginEdit(nextCell);
                    }
                }
            }
        },
        // 保留原有配置
    );
    
  2. 移除handleKeyEvent中无效的移动端代码
    原代码中监听移动端arrowDown的逻辑对Next按钮无作用,可直接删除:

    @override
    void handleKeyEvent(RawKeyEvent keyEvent) {
      if (keyEvent.logicalKey == LogicalKeyboardKey.tab) {
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
          dataGridController.beginEdit(dataGridController.currentCell);
        });
      }
      if(keyEvent.logicalKey == LogicalKeyboardKey.f2){
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
          dataGridController.beginEdit(dataGridController.currentCell);
        });
      }
      // 删除移动端arrowDown相关判断
      super.handleKeyEvent(keyEvent);
    }
    
  3. 优化焦点管理(可选)
    若自定义编辑组件使用了focusNode,跳转时主动释放当前焦点,避免异常:

    onSubmitted: (_) {
        _focusNode.unfocus();
        // 后续跳转逻辑同上
    }
    

内容的提问来源于stack exchange,提问作者Daniel Ardison

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 18:45:29