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

InkWell内设置keyboardType为number的TextField触发涟漪效果问题

Flutter踩坑:数字键盘TextField触发外层InkWell涟漪效果

问题详情

在InkWell组件内部使用配置了keyboardType: TextInputType.number的TextField时,输入内容会同时触发InkWell的涟漪动画。该问题仅在以下场景出现:

  • Android模拟器及真实设备
  • 连接硬件键盘的iOS模拟器

复现代码

Material(
      color: Colors.white,
      child: Center(
        child: SizedBox(
          height: 100,
          width: 200,
          child: InkWell(
            onTap: () {},
            child: const Center(
              child: SizedBox(
                height: 50,
                width: 100,
                child: TextField(
                  keyboardType: TextInputType.number, // 问题触发点
                  decoration: InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'Test',
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    )

效果演示

数字键盘触发InkWell涟漪

解决办法

方法1:用GestureDetector拦截手势

在TextField外层套一个GestureDetector,设置behavior: HitTestBehavior.opaque,让它把点击事件拦下来,不让事件冒泡到外层的InkWell:

Material(
  color: Colors.white,
  child: Center(
    child: SizedBox(
      height: 100,
      width: 200,
      child: InkWell(
        onTap: () {},
        child: const Center(
          child: SizedBox(
            height: 50,
            width: 100,
            child: GestureDetector(
              behavior: HitTestBehavior.opaque,
              child: TextField(
                keyboardType: TextInputType.number,
                decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'Test',
                ),
              ),
            ),
          ),
        ),
      ),
    ),
  ),
)

方法2:给TextField加空的onTap回调

给TextField设置一个空的onTap回调,这样TextField会自己消费掉点击事件,不会把事件传递给外层的InkWell:

Material(
  color: Colors.white,
  child: Center(
    child: SizedBox(
      height: 100,
      width: 200,
      child: InkWell(
        onTap: () {},
        child: const Center(
          child: SizedBox(
            height: 50,
            width: 100,
            child: TextField(
              keyboardType: TextInputType.number,
              onTap: () {}, // 空回调拦截事件
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                labelText: 'Test',
              ),
            ),
          ),
        ),
      ),
    ),
  ),
)

方法3:替换成InkResponse组件

如果业务允许,把InkWell换成InkResponse,并开启containedInkWell: true,这样涟漪效果只会限制在子组件范围内,输入时就不会触发外层的涟漪了:

Material(
  color: Colors.white,
  child: Center(
    child: SizedBox(
      height: 100,
      width: 200,
      child: InkResponse(
        containedInkWell: true,
        onTap: () {},
        child: const Center(
          child: SizedBox(
            height: 50,
            width: 100,
            child: TextField(
              keyboardType: TextInputType.number,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                labelText: 'Test',
              ),
            ),
          ),
        ),
      ),
    ),
  ),
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 20:38:13