Come visualizzare l'indice di scorrimento per scrollController in flutter?
Vorrei visualizzare l'indice nella parte inferiore di listView utilizzando lo scrollController, nello stesso modo in cui viene visualizzato nell'immagine seguente:

Dopo che l'utente scorre verso il basso o verso l'alto, il conteggio a sinistra, evidenziato in rosso, viene aumentato / diminuito in base alla direzione di scorrimento dell'utente.
Quello che voglio ottenere è aggiornare automaticamente l'indice dell'oggetto visualizzato, indicato in rosso sull'immagine. Pertanto, ogni volta che l'utente scorre verso il basso o verso l'alto, questo indice viene aggiornato dall'indice dell'elemento visualizzato.
L'immagine mostra che ho raggiunto il 26 ° elemento. Ogni volta che scorro verso il basso o verso l'alto, questo indice viene aggiornato.
Ho provato a utilizzare l'offset che viene emesso per l'evento di scorrimento senza fortuna.
Risposte
Il modo è usare il controller di scorrimento come facevi tu.
È necessario utilizzare una dimensione di elemento nota e un ascoltatore.
// 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'aggiunta di un listener a uno scrollController chiamerà la richiamata fornita ogni volta che l'elenco viene fatto scorrere. Puoi gestire molti comportamenti dell'elenco utilizzando la stessa logica, inclusa l'identificazione del tipo di evento che ha attivato l'ascoltatore, la direzione dello scorrimento, ecc.
C'è una libreria chiamata scroll to index che potrebbe aiutarti. Potresti prendere $ index da mostrare all'interno del tuo messaggio di avviso. L'esempio qui sotto è dell'autore della libreria:
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-d13d3c20d68bForse questo ti può aiutare. È disponibile anche il codice sorgente. Una semplice matematica sull'altezza dell'oggetto potrebbe aiutare.