Skip to content

Instantly share code, notes, and snippets.

@MiniSuperDev
Created May 12, 2022 03:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MiniSuperDev/daae1ebcca5195bbdafcedb0c0338ffb to your computer and use it in GitHub Desktop.
Save MiniSuperDev/daae1ebcca5195bbdafcedb0c0338ffb to your computer and use it in GitHub Desktop.
scroll-to-index not work when use a center key
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, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final scrollDirection = Axis.vertical;
late AutoScrollController controller;
late int counter;
List<int> top = [];
List<int> bottom = [];
bool hasCenterKey = true;
@override
void initState() {
super.initState();
controller = _getController();
updateTop();
bottom = List<int>.generate(30, (i) => i);
counter = top.last;
}
void updateTop() {
if (hasCenterKey) {
top = List<int>.generate(30, (i) => -(i + 1));
} else {
top = List<int>.generate(30, (i) => -(30 - i));
}
}
AutoScrollController _getController() {
return AutoScrollController(
axis: scrollDirection,
);
}
void addItems() {
setState(() {
top = List<int>.generate(30, (i) => -(30 + 1 - i));
});
}
final Key centerKey = ValueKey('second-sliver-list');
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: [
ElevatedButton(
onPressed: () {
setState(() {
hasCenterKey = !hasCenterKey;
updateTop();
});
},
child: Text('CENTER KEY - ' + (hasCenterKey ? 'ON' : 'OFF')),
),
IconButton(
onPressed: () async {
final index = hasCenterKey ? top.last : top.first;
await controller.scrollToIndex(index);
controller.highlight(index);
},
icon: Text('First'),
),
IconButton(
onPressed: () async {
await controller.scrollToIndex(bottom.last);
controller.highlight(bottom.last);
},
icon: Text('Last'),
),
],
),
body: _buildNestedListView(),
floatingActionButton: FloatingActionButton(
onPressed: _nextCounter,
tooltip: 'Increment',
child: Text(counter.toString()),
),
);
}
Widget _buildNestedListView() {
return NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) => [
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
sliver: SliverAppBar(),
)
],
body: CustomScrollView(
center: hasCenterKey ? centerKey : null,
scrollDirection: Axis.vertical,
controller: controller,
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
final data = top[index];
return Padding(
padding: EdgeInsets.all(8),
child: _getRow(data, data, 50, controller),
);
},
childCount: top.length,
),
),
SliverToBoxAdapter(
child: Container(
height: 50,
color: Colors.red,
),
),
SliverList(
key: centerKey,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
final data = bottom[index];
return Padding(
padding: EdgeInsets.all(8),
child: _getRow(data, data, 50, controller),
);
},
childCount: bottom.length,
),
),
],
),
);
}
Future _nextCounter() async {
setState(() {
if (counter >= bottom.last) {
counter = top.last;
} else if ((counter + 10) <= bottom.last) {
counter = counter + 10;
} else {
counter++;
}
});
await _scrollToCounter();
}
Future _scrollToCounter() async {
final result = await controller.scrollToIndex(counter,
preferPosition: AutoScrollPosition.begin);
print(result);
controller.highlight(counter);
}
Widget _getRow(
int index, int value, double height, AutoScrollController controller) {
return _wrapScrollTag(
index: index,
controller: controller,
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, value: $value'),
));
}
Widget _wrapScrollTag({
required int index,
required Widget child,
required AutoScrollController controller,
}) =>
AutoScrollTag(
key: ValueKey(index),
controller: controller,
index: index,
child: child,
highlightColor: Colors.green.withOpacity(0.5),
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment