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

使用Dismissible包裹列表项后ListView无法滚动的问题

问题解决:Dismissible包裹列表项后双指悬停滚动失效

原因分析

Dismissible组件默认会拦截水平拖拽手势,双指滚动的手势信号被其手势识别器优先捕获,导致ListView无法响应滚动操作;同时2GB内存的模拟器性能有限,手势冲突的问题会被进一步放大。

解决方案

方案1:指定拖拽方向并调整手势优先级

通过配置gestureRecognizers,让Dismissible仅在特定区域响应拖拽,同时允许滚动手势优先处理:

return Dismissible(
  key: ValueKey(expenses[index]),
  onDismissed: (direction) {
    removeItem(expenses[index]);
  },
  // 仅支持从右往左拖拽删除
  direction: DismissDirection.endToStart,
  // 配置手势识别逻辑,避免拦截滚动手势
  gestureRecognizers: <Type, GestureRecognizer>{
    HorizontalDragGestureRecognizer:
        HorizontalDragGestureRecognizer()
          ..onStart = (details) {
            // 仅在列表项右侧20%区域拖拽时触发删除
            if (details.localPosition.dx > MediaQuery.of(context).size.width * 0.8) {
              // 保留Dismissible的拖拽逻辑
            } else {
              // 不拦截手势,交给ListView处理滚动
              GestureBinding.instance.pointerRouter.route(details);
            }
          },
  },
  background: Container(
    color: Theme.of(context).colorScheme.error.withOpacity(0.75),
    margin: EdgeInsets.symmetric(
      horizontal: Theme.of(context).cardTheme.margin!.horizontal,
    ),
  ),
  child: ExpenseItem(
    expense: expenses[index],
  ),
);

方案2:强制ListView的滚动物理特性

给ListView.builder添加physics属性,确保滚动功能始终生效:

return ListView.builder(
  physics: const AlwaysScrollableScrollPhysics(), // 强制启用滚动
  itemCount: expenses.length,
  itemBuilder: (ctx, index) {
    // 你的Dismissible代码
  },
);

方案3:优化低内存模拟器性能

  • 确保所有可复用Widget使用const构造(你的代码已实现)
  • 关闭模拟器不必要功能(如GPU渲染、动画缩放)
  • 测试时减少列表数据量,避免内存过载导致手势响应延迟

修改后的完整代码示例

import 'package:expense_tracker/models/expense.dart';
import 'package:expense_tracker/widgets/expenses_list/expense_item.dart';
import 'package:flutter/material.dart';

class ExpensesList extends StatelessWidget {
  final List<Expense> expenses;
  final void Function(Expense item) removeItem;
  const ExpensesList(
      {super.key, required this.expenses, required this.removeItem});

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      physics: const AlwaysScrollableScrollPhysics(),
      itemCount: expenses.length,
      itemBuilder: (ctx, index) {
        return Dismissible(
          key: ValueKey(expenses[index]),
          direction: DismissDirection.endToStart,
          onDismissed: (direction) {
            removeItem(expenses[index]);
          },
          gestureRecognizers: <Type, GestureRecognizer>{
            HorizontalDragGestureRecognizer:
                HorizontalDragGestureRecognizer()
                  ..onStart = (details) {
                    if (details.localPosition.dx > MediaQuery.of(context).size.width * 0.8) {
                      // 仅右侧区域触发删除
                    } else {
                      GestureBinding.instance.pointerRouter.route(details);
                    }
                  },
          },
          background: Container(
            color: Theme.of(context).colorScheme.error.withOpacity(0.75),
            margin: EdgeInsets.symmetric(
              horizontal: Theme.of(context).cardTheme.margin!.horizontal,
            ),
          ),
          child: ExpenseItem(
            expense: expenses[index],
          ),
        );
      },
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 07:22:52