Skip to content

Instantly share code, notes, and snippets.

@gaaclarke
Created October 24, 2019 17:54
Show Gist options
  • Save gaaclarke/4200741c4413707f0f73a887bf5d9b39 to your computer and use it in GitHub Desktop.
Save gaaclarke/4200741c4413707f0f73a887bf5d9b39 to your computer and use it in GitHub Desktop.
Scroll to Index ListView
import 'package:flutter/material.dart';
/// An interface for representing the contents of a ListView.
class ListViewDataSource {
/// The number of items that will be displayed in the ListView.
int get numItems => 0;
/// The height of the widget at [index].
double itemHeight(int index) => 0;
/// Generate the widget at [index].
Widget build(BuildContext context, int index) => null;
/// Calculates the offset of a widget at [index]. If you scroll to that
/// index, that item will be at the top of the ListView.
static double itemOffset(ListViewDataSource dataSource, int index) {
if (index >= dataSource.numItems) {
throw new RangeError("index out of range");
}
double result = 0.0;
for (int i = 0; i < index; ++i) {
result += dataSource.itemHeight(i);
}
return result;
}
/// A factory function that makes a [ListView] that displays the contents of a
/// [ListViewDataSource].
static ListView makeListView(
{ScrollController controller,
EdgeInsetsGeometry padding,
@required ListViewDataSource dataSource}) {
return ListView.builder(
controller: controller,
padding: padding,
itemCount: dataSource.numItems,
itemBuilder: dataSource.build,
);
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
/// An example of an [ListViewDataSource].
class FooDataSource implements ListViewDataSource {
int get numItems => 50;
double itemHeight(int index) => (index % 3) * 50.0;
Widget build(BuildContext context, int index) {
return Container(
height: itemHeight(index),
color: Colors.amber[(index % 9) * 100],
child: const Center(child: Text('Entry A')),
);
}
}
class _MyHomePageState extends State<MyHomePage> {
final ScrollController _scrollController = new ScrollController();
final ListViewDataSource _dataSource = new FooDataSource();
void _performScroll() {
int targetIndex = 3;
_scrollController.animateTo(
ListViewDataSource.itemOffset(_dataSource, targetIndex),
duration: const Duration(milliseconds: 100),
curve: Curves.easeInOut);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: ListViewDataSource.makeListView(
controller: _scrollController,
padding: const EdgeInsets.all(8),
dataSource: _dataSource,
),
),
floatingActionButton: FloatingActionButton(
onPressed: _performScroll,
tooltip: 'Perform Scroll',
child: Icon(Icons.add),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment