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

Flutter中如何避免拖动滑块时ListTile列表项重复显示?

滑块筛选女生列表时重复显示结果的解决方法

问题描述

我通过滑块指定距离范围展示女生列表,应用加载时能正常显示20km范围内的2位女生,但拖动滑块到30km时,新的3位女生会重复追加在原有结果后面。需要实现拖动滑块时仅显示当前距离范围内的新结果,清除之前的内容。

相关代码

girls.dart

class Girls {
  String name;
  int distance;

  Girls(this.name, this.distance);
}

girls_screen.dart

import 'package:flutter/material.dart';
import 'package:switch_circle_color/model/girls.dart';

class GirlsScreen extends StatefulWidget {
  GirlsScreen({Key? key}) : super(key: key);

  @override
  State<GirlsScreen> createState() => _GirlsScreenState();
}

class _GirlsScreenState extends State<GirlsScreen> {
  int distance = 15;

  void changeDistance(double num) {
    setState(() {
      distance = num.round();

      populateFilteredGirls(distance);
      this.filteredGirls = filteredGirls;
    });
  }

  List<Girls> allGirls = [
    Girls("Reshmita", 25),
    Girls("Ankita", 17),
    Girls("Rupali", 42),
    Girls("Monica", 50),
    Girls("Sakshi", 9)
  ];

  List<Girls> filteredGirls = [];

  @override
  void initState() {
    super.initState();
    //filteredGirls = allGirls;
    distance = 20;
    allGirls.sort((a, b) => a.distance.compareTo(b.distance));
    populateFilteredGirls(distance);
  }

  void populateFilteredGirls(int dis) {
    for (int i = 0; i < allGirls.length; i++) {
      if (allGirls[i].distance <= dis) {
        filteredGirls.add(allGirls[i]);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: Column(
        children: [
          Padding(padding: EdgeInsets.all(20)),
          Slider(
            min: 1.0,
            max: 100.0,
            divisions: 100,
            activeColor: Colors.green,
            inactiveColor: Colors.orange,
            label: 'Set distance value',
            value: distance.toDouble(),
            onChanged: (value) {
              changeDistance(value);
            },
          ),
          Padding(padding: EdgeInsets.all(10)),
          Text("Current distance is $distance kms"),
          Padding(padding: EdgeInsets.all(10)),
          Expanded(
            child: ListView.builder(
              itemCount: filteredGirls.length,
              itemBuilder: (BuildContext context, int index) {
                return ListTile(
                  leading: const Icon(Icons.girl_outlined),
                  trailing: Text("${filteredGirls[index].distance} km away"),
                  title: Text("${filteredGirls[index].name}"),
                );
              },
            ),
          ),
        ],
      ),
    ));
  }
}

解决方案

问题根源在于populateFilteredGirls方法每次调用时,没有清空旧的filteredGirls列表,而是直接追加新数据,导致旧结果一直保留。

方法一:清空列表后重新添加

在populateFilteredGirls方法开头先清空列表,再筛选添加符合条件的女生:

void populateFilteredGirls(int dis) {
  filteredGirls.clear(); // 清空旧数据
  for (int i = 0; i < allGirls.length; i++) {
    if (allGirls[i].distance <= dis) {
      filteredGirls.add(allGirls[i]);
    }
  }
}

方法二:直接生成新列表(更简洁)

利用Dart的where方法直接筛选出符合条件的女生,生成新列表替换原有的filteredGirls:

void populateFilteredGirls(int dis) {
  filteredGirls = allGirls.where((girl) => girl.distance <= dis).toList();
}

额外优化

changeDistance方法里的this.filteredGirls = filteredGirls;是多余的,可以删除,因为populateFilteredGirls已经修改了列表,加上setState会自动触发UI重建:

void changeDistance(double num) {
  setState(() {
    distance = num.round();
    populateFilteredGirls(distance);
  });
}

修改完成后,拖动滑块时就会只显示当前距离范围内的女生,不会再出现重复内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 12:03:24