Comment afficher l'index de défilement pour scrollController en flutter?
Je voudrais afficher l'index en bas de la listView en utilisant le scrollController, de la même manière qu'il est affiché dans l'image suivante:
Une fois que l'utilisateur fait défiler vers le bas ou vers le haut, le compte à gauche, mis en évidence en rouge, augmente / diminue en fonction de la direction de défilement de l'utilisateur.
Ce que je souhaite, c'est mettre à jour automatiquement l'index de l'élément affiché, indiqué en rouge sur l'image. Ainsi, chaque fois que l'utilisateur fait défiler vers le bas ou vers le haut, cet index est mis à jour par l'index de l'élément affiché.
La photo montre que j'ai atteint le 26e élément. Chaque fois que je fais défiler vers le bas ou vers le haut, cet index est mis à jour.
J'ai essayé d'utiliser le décalage qui est émis pour l'événement de défilement sans succès.
Réponses
La méthode consiste à utiliser le contrôleur de défilement comme vous le faisiez.
Vous devez utiliser une taille d'élément connue et un écouteur.
// Declaring the controller and the item size
ScrollController _scrollController;
final itemSize = 100.0;
// Initializing
@override
void initState() {
_scrollController = ScrollController();
_scrollController.addListener(_scrollListener);
super.initState();
}
// Your list widget (must not be nested lists)
ListView.builder(
controller: _scrollController,
itemCount: <Your list length>,
itemExtent: itemSize,
itemBuilder: (context, index) {
return ListTile(<your items>);
},
),
// With the listener and the itemSize, you can calculate which item
// is on screen using the provided callBack. Something like this:
void _scrollListener() {
setState(() {
var index = (_scrollController.offset / itemSize).round() + 1;
});
}
L'ajout d'un écouteur à un scrollController appellera le rappel fourni à chaque fois que la liste défile. Vous pouvez gérer de nombreux comportements de la liste en utilisant la même logique, notamment en identifiant le type d'événement qui a déclenché l'auditeur, la direction du défilement, etc.
Il existe une bibliothèque appelée scroll to index qui pourrait vous aider. Vous pouvez utiliser l'index $ pour l'afficher dans votre message toast. L'exemple ci-dessous est de l'auteur de la lib:
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Scroll To Index Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Scroll To Index Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
static const maxCount = 100;
final random = math.Random();
final scrollDirection = Axis.vertical;
AutoScrollController controller;
List<List<int>> randomList;
@override
void initState() {
super.initState();
controller = AutoScrollController(
viewportBoundaryGetter: () => Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom),
axis: scrollDirection
);
randomList = List.generate(maxCount, (index) => <int>[index, (1000 * random.nextDouble()).toInt()]);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView(
scrollDirection: scrollDirection,
controller: controller,
children: randomList.map<Widget>((data) {
return Padding(
padding: EdgeInsets.all(8),
child: _getRow(data[0], math.max(data[1].toDouble(), 50.0)),
);
}).toList(),
),
floatingActionButton: FloatingActionButton(
onPressed: _scrollToIndex,
tooltip: 'Increment',
child: Text(counter.toString()),
),
);
}
int counter = -1;
Future _scrollToIndex() async {
setState(() {
counter++;
if (counter >= maxCount)
counter = 0;
});
await controller.scrollToIndex(counter, preferPosition: AutoScrollPosition.begin);
controller.highlight(counter);
}
Widget _getRow(int index, double height) {
return _wrapScrollTag(
index: index,
child: Container(
padding: EdgeInsets.all(8),
alignment: Alignment.topCenter,
height: height,
decoration: BoxDecoration(
border: Border.all(
color: Colors.lightBlue,
width: 4
),
borderRadius: BorderRadius.circular(12)
),
child: Text('index: $index, height: $height'),
)
);
}
Widget _wrapScrollTag({int index, Widget child})
=> AutoScrollTag(
key: ValueKey(index),
controller: controller,
index: index,
child: child,
highlightColor: Colors.black.withOpacity(0.1),
);
}
https://medium.com/flutter-community/create-shop-list-with-flutter-d13d3c20d68bPeut-être que celui-ci peut vous aider. Le code source est également disponible. Un calcul simple sur la hauteur des éléments peut aider.