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
相关产品推荐
相关产品推荐

