问题
I'm trying to make a Listview whose top element should have a different UI then the rest. And the Listview is scrollable so the item which is visible and at the top of the list should be highlighted with different UI. Refer to this image.
I want when I scroll through the list the top item at that instant should have a different UI ( the highlighted orange color).
How can I do this in flutter?
回答1:
This is still an open Github issue about this.
However, there are some packages here that can help you achieve this (Not sure about the performance with long lists).
Do check out the scrollable_positioned_list from the above link. It provides a listener by which the visible items can be monitored as follows:
itemPositionsListener.positions.addListener((positions) => ...);
回答2:
I would suggest you to checkout visibility_detector package. The example for visibility_detector (https://pub.dev/packages/visibility_detector/example) package does almost exactly what you want. The example displays the index of all the List Items currently visible on the screen.
回答3:
wrap element zero in a different coloured Container();
回答4:
It depends on what widgets you are using, but here is the general idea. There are two things you could do.
If you have a limited amount of list items, then you might want to use a StatefulWidget
and have an int
(or a List<int>
) as a member to keep reference of the highlighted widget(s).
class SomeWidget extends StatefulWidget {
final List<int> elements;
const SomeWidget({Key key, this.elements}) : super(key: key);
@override
_SomeWidgetState createState() => _SomeWidgetState();
}
class _SomeWidgetState extends State<SomeWidget> {
List<int> highlightedIndices = List();
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: widget.elements.length,
itemBuilder: (context, index) => FlatButton(
color: highlightedIndices.contains(index) ? Colors.white : Colors.red,
child: Text('$index'),
onPressed: () => setState(() {
if(highlightedIndices.contains(index))
highlightedIndices.remove(index);
else highlightedIndices.add(index);
}),
),
),
);
}
If you have a lot of items in your ListView
you'd be better off using a model class that extends ChangeNotifier
, and then have a ChangeNotifierProvider
wrap your widget
. You need to add provider
package in your pubspec.yaml
file.
pubspec.yaml
provider: ^4.3.2+2
ChangeNotifier
class SomeModel with ChangeNotifier {
bool _isHighlighted = false;
bool get isHighlighted => _isHighlighted;
void highlight() {
_isHighlighted = ! _isHighlighted;
notifyListeners();
}
}
build method
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: widget.elements.length,
itemBuilder: (context, index) => ChangeNotifierProvider<SomeModel>(
create: (_) => SomeModel(),
builder: (context, child) => Consumer<SomeModel>(
builder: (context, value, child) => FlatButton(
color: value.isHighlighted ? Colors.white : Colors.red,
child: Text('$index'),
onPressed: value.highlight
),
),
),
),
);
来源:https://stackoverflow.com/questions/64782446/how-to-highlight-top-item-of-listview-in-flutter