Как проскролить до нужного виджета в ListView?

Чтобы прокрутить до определенного элемента в ListView
на Flutter, можно использовать ScrollController
. Вот пример того, как это можно сделать:
- Создайте
ScrollController
и прикрепите его к вашемуListView
. - Вызовите метод
animateTo
для прокрутки до нужной позиции.
Пример кода:
import 'package:flutter/material.dart';
class ScrollToListView extends StatefulWidget {
@override
_ScrollToListViewState createState() => _ScrollToListViewState();
}
class _ScrollToListViewState extends State<ScrollToListView> {
final ScrollController _scrollController = ScrollController();
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
void _scrollToIndex(int index) {
final double position = index * 100.0; // Здесь 100.0 — это высота одного элемента.
_scrollController.animateTo(
position,
duration: Duration(seconds: 1),
curve: Curves.easeInOut,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Scroll to List Item'),
),
body: Column(
children: [
Expanded(
child: ListView.builder(
controller: _scrollController,
itemCount: 50,
itemBuilder: (context, index) {
return Container(
height: 100.0,
color: index % 2 == 0 ? Colors.blue : Colors.green,
child: Center(
child: Text(
'Item $index',
style: TextStyle(fontSize: 24),
),
),
);
},
),
),
ElevatedButton(
onPressed: () => _scrollToIndex(20), // Пример прокрутки до 20-го элемента.
child: Text('Scroll to 20th item'),
),
],
),
);
}
}
void main() => runApp(MaterialApp(home: ScrollToListView()));
Объяснение:
- Используем
ScrollController
для управления прокруткой. - Метод
animateTo
принимает позицию в пикселях, до которой нужно проскролить. Для определения позиции умножаем индекс на высоту элемента. - Также можно использовать
jumpTo
, если анимация не важна.
Если элементы в ListView
имеют разную высоту, тогда для корректного скроллинга до определенного элемента можно использовать GlobalKey
для каждого элемента списка и вычислять их положение в списке динамически. Вот пример того, как это можно сделать:
import 'package:flutter/material.dart';
class ScrollToDynamicHeightListView extends StatefulWidget {
@override
_ScrollToDynamicHeightListViewState createState() => _ScrollToDynamicHeightListViewState();
}
class _ScrollToDynamicHeightListViewState extends State<ScrollToDynamicHeightListView> {
final ScrollController _scrollController = ScrollController();
final List<GlobalKey> _keys = List.generate(50, (index) => GlobalKey());
void _scrollToIndex(int index) {
final keyContext = _keys[index].currentContext;
if (keyContext != null) {
Scrollable.ensureVisible(
keyContext,
duration: Duration(seconds: 1),
curve: Curves.easeInOut,
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Scroll to List Item with Dynamic Height'),
),
body: Column(
children: [
Expanded(
child: ListView.builder(
controller: _scrollController,
itemCount: 50,
itemBuilder: (context, index) {
return Container(
key: _keys[index],
height: (index % 2 == 0) ? 150.0 : 100.0, // Элементы разной высоты
color: index % 2 == 0 ? Colors.blue : Colors.green,
child: Center(
child: Text(
'Item $index',
style: TextStyle(fontSize: 24),
),
),
);
},
),
),
ElevatedButton(
onPressed: () => _scrollToIndex(20), // Пример прокрутки до 20-го элемента
child: Text('Scroll to 20th item'),
),
],
),
);
}
}
void main() => runApp(MaterialApp(home: ScrollToDynamicHeightListView()));
Объяснение:
- Каждому элементу списка присваивается уникальный
GlobalKey
, что позволяет получить его текущее положение на экране черезcurrentContext
. - Функция
Scrollable.ensureVisible
автоматически скроллит до выбранного элемента, независимо от его высоты. - Это решение особенно полезно, когда высота элементов списка динамична и не фиксирована.
Таким образом, можно прокручивать список с элементами разной высоты до нужного элемента без необходимости вычислять его позицию вручную.