Flutter如何制作可选择/聚焦小部件

3
我正在创建一个安卓电视应用。我一直试图解决的问题是,为什么当我点击遥控器上的向上和向下箭头按钮时,似乎没有任何反应,也没有选择任何列表项。
最后,我发现如果在列表中使用可获取焦点的提高按钮或其他小部件,我可以使用箭头键,并且它可以正常工作。之前,我使用了包裹在手势检测器中的卡片小部件。
所以我想知道,按钮和带手势检测器的卡片之间的区别是什么,导致箭头键无法选择项目。我猜测这是焦点造成的。
以下是我之前使用的不允许遥控器上的上下键选择的内容:
GestureDetector(
    child: Card(
      color: color,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(15.0),
      ),
      elevation: 10,
      child: SizedBox(
          width: (width / numberOfCards) - padding * (numberOfCards - 1),
          height: (height / 2) - padding * 2,
          child: Center(child: Text(cardTitle, style: Theme.of(context).textTheme.bodyText1?.copyWith(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white),))),
    ),
    onTap: () => onCardTap(),
  ),

这是我替换后的按钮,使得上下键和选择键起作用:

ElevatedButton(
                  onPressed: () {},
                  child: Text('Test 1', style: Theme.of(context).textTheme.bodyText1?.copyWith(color: Colors.white, fontSize: 18, fontWeight: FontWeight.normal)),
                  style: ButtonStyle(
                      backgroundColor: MaterialStateProperty.all(Colors.grey.withOpacity(0.3)),
                      minimumSize: MaterialStateProperty.all(Size(60, 60)),
                      elevation: MaterialStateProperty.all(10),
                      shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: new BorderRadius.circular(50)),)),
                ),

如果需要,这是我正在使用的方法来捕获按键操作:

Shortcuts(
  shortcuts: <LogicalKeySet, Intent>{
    LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(),
  },

谢谢

1个回答

5

你的gesture detector组件与ElevatedButton组件的区别在于,你没有一个 FocusNode

如果你深入了解ElevatedButton的实现细节,你会发现它使用了一个带有FocusNodeInkWell

final Widget result = ConstrainedBox(
  constraints: effectiveConstraints,
  child: Material(
    // ...
    child: InkWell(
      // ...
      focusNode: widget.focusNode,
      canRequestFocus: widget.enabled,
      onFocusChange: updateMaterialState(MaterialState.focused),
      autofocus: widget.autofocus,
      // ...
      child: IconTheme.merge(
        // ....
        child: Padding(
          padding: padding,
          child: // ...
          ),
        ),
      ),
    ),
  ),
);

因此,如果您将GestureDetector替换为Inkwell,则键盘导航将正常工作。

InkWell(
  child: Card(
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(15.0),
    ),
    elevation: 10,
    child: const SizedBox(
      width: 200,
      height: 60,
      child: Center(
        child: Text(
          'Test 1',
        ),
      ),
    ),
  ),
  onTap: () {},
)

(Tested on Android TV emulator API 30, with keyboard and d-pad.)

参考资料


如果关心无障碍性,那么应该避免使用GestureDetector。需要外部开关/键盘的用户无法激活任何GestureDetector。 - chemturion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接