Wie wird der Bildlaufindex für scrollController im Flattern angezeigt?
Ich möchte den Index am Ende der Listenansicht mithilfe des scrollControllers anzeigen, so wie er im folgenden Bild angezeigt wird:
Nachdem der Benutzer nach unten oder oben gescrollt hat, wird die Anzahl der links hervorgehobenen, rot hervorgehobenen Zeichen basierend auf der Bildlaufrichtung des Benutzers erhöht / verringert.
Was ich erreichen möchte, ist die automatische Aktualisierung des Index des angezeigten Elements, der auf dem Bild rot angezeigt wird. Wenn der Benutzer nach unten oder oben scrollt, wird dieser Index durch den Index des angezeigten Elements aktualisiert.
Das Bild zeigt, dass ich den 26. Punkt erreicht habe. Immer wenn ich nach unten oder oben scrolle, wird dieser Index aktualisiert.
Ich habe versucht, den Offset zu verwenden, der für das Bildlaufereignis ausgegeben wird, ohne Glück.
Antworten
Der Weg ist, den Scroll-Controller so zu verwenden, wie Sie es getan haben.
Sie müssen eine bekannte Elementgröße und einen Listener verwenden.
// 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;
});
}
Wenn Sie einem scrollController einen Listener hinzufügen, wird der Rückruf jedes Mal aufgerufen, wenn die Liste gescrollt wird. Sie können viele Verhaltensweisen der Liste mit derselben Logik behandeln, einschließlich der Identifizierung des Ereignistyps, der den Listener ausgelöst hat, der Richtung des Bildlaufs usw.
Es gibt eine Bibliothek namens scroll to index , die Ihnen helfen könnte. Sie können den $ -Index verwenden, um ihn in Ihrer Toastnachricht anzuzeigen. Das folgende Beispiel stammt vom Autor der Bibliothek:
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-d13d3c20d68bVielleicht kann dir dieser helfen. Auch Quellcode ist verfügbar. Eine einfache Berechnung der Artikelhöhe könnte hilfreich sein.