更改 ListView 中当前顶部可见项的颜色 - Flutter
Posted
技术标签:
【中文标题】更改 ListView 中当前顶部可见项的颜色 - Flutter【英文标题】:Change the color of current top visible item in ListView - Flutter 【发布时间】:2020-09-09 23:41:03 【问题描述】:当用户滚动列表时,我希望列表中的顶部可见项目改变颜色。
我得到的最接近的是插件 ScrollablePositionedList: https://pub.dev/packages/scrollable_positioned_list
当我热重载时,列表中的第一项现在会改变颜色或顶部屏幕上的任何一项。但是当我滚动时,它们不会实时进行。
我非常感谢任何帮助。请在下面找到相关代码。提前致谢!
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:scrollviewexperiment/models/place_data.dart';
import 'package:scrollviewexperiment/widgets/place_tile.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
class PlacesList extends StatefulWidget
@override
_PlacesListState createState() => _PlacesListState();
class _PlacesListState extends State<PlacesList>
final ItemPositionsListener itemPositionsListener =
ItemPositionsListener.create();
ItemScrollController _itemScrollController = ItemScrollController();
int currentIndex = 0;
@override
void initState()
super.initState();
currentVisibleIndex();
@override
Widget build(BuildContext context)
return Consumer<PlaceData>(
builder: (context, placeData, child)
return ScrollablePositionedList.builder(
itemCount: placeData.placeCount,
itemPositionsListener: itemPositionsListener,
itemBuilder: (context, index)
final place = placeData.places[index];
return Card(
color: index == currentIndex ? Colors.blue : Colors.white,
elevation: 2.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
child: PlaceTile(
placeName: place.name,
distance: place.distance,
),
);
,
);
,
);
currentVisibleIndex()
itemPositionsListener.itemPositions.addListener(()
int min;
if (itemPositionsListener.itemPositions.value.isNotEmpty)
min = itemPositionsListener.itemPositions.value
.where((ItemPosition position) => position.itemTrailingEdge > 0)
.reduce((ItemPosition min, ItemPosition position) =>
position.itemTrailingEdge < min.itemTrailingEdge
? position
: min)
.index;
print('Min Index $min');
currentIndex = min;
);
【问题讨论】:
【参考方案1】:我想通了!
我在 ScrollablePositionedList.builder 的 itemBuilder 中返回了一个 ValueListenableBuilder
这不是世界上最干净的解决方案,所以如果有人可以对此进行改进,我很想知道。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:scrollviewexperiment/models/place_data.dart';
import 'package:scrollviewexperiment/widgets/place_tile.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
class PlacesList extends StatefulWidget
@override
_PlacesListState createState() => _PlacesListState();
class _PlacesListState extends State<PlacesList>
final ItemPositionsListener itemPositionsListener =
ItemPositionsListener.create();
@override
Widget build(BuildContext context)
return Consumer<PlaceData>(
builder: (context, placeData, child)
return ScrollablePositionedList.builder(
itemCount: placeData.placeCount,
itemPositionsListener: itemPositionsListener,
itemBuilder: (context, index)
final place = placeData.places[index];
return ValueListenableBuilder<Iterable<ItemPosition>>(
valueListenable: itemPositionsListener.itemPositions,
builder: (context, positions, child)
int min;
if (positions.isNotEmpty)
min = positions
.where((ItemPosition position) =>
position.itemTrailingEdge > 0)
.reduce((ItemPosition min, ItemPosition position) =>
position.itemTrailingEdge < min.itemTrailingEdge
? position
: min)
.index;
return Card(
color: index == min ? Colors.blue : Colors.white,
elevation: 2.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
child: PlaceTile(
placeName: place.name,
distance: place.distance,
),
);
,
);
,
);
,
);
【讨论】:
以上是关于更改 ListView 中当前顶部可见项的颜色 - Flutter的主要内容,如果未能解决你的问题,请参考以下文章
Flutter Using ListView.Builder:如何在我选择的所有项目上仅更改一项的背景颜色
在 Android 上更改 ListView 项目的背景颜色