quire-io / scroll-to-index Goto Github PK
View Code? Open in Web Editor NEWscroll to index with fixed/variable row height inside Flutter scrollable widget
License: MIT License
scroll to index with fixed/variable row height inside Flutter scrollable widget
License: MIT License
I can see how one can scroll to subsequent indexes, but is it possible using this plugin to implement scrolling to the index of the next element displayed? What I mean here is a scenario where I scroll the view to show some element in the middle of the list I would like to scroll to the element that is positioned below the currently displayed element. Or to rephrase the question, is it possible to get the index of the currently displayed element and scroll to the one directly below/above it?
When the ListView scrolls to the bottom, the bottom entry and some of the entries on the bottom cannot be scrolled to the begin position. Is there any good solution?
my widget will created dynamically using ListView.builder
, so it's not fixed at beginning.
is it possible to use this plugin ?
thanks
A nice implementation, you're welcome on the awesome flutter repo if you want to PR !
https://github.com/Solido/awesome-flutter
I want to be able to relate the left and right sides of how to operate?
In the following picture, when I scroll on the right side, I hope that the left side can be positioned to the specific location. How to operate?
Now I can click right and left to associate right and left, but can't scroll right to associate left?
Hi,
first of all, thanks for providing this package, this saved me a lot of time. I'm using the AutoScrollController
in a CustomScrollVIew
. I would like to change the opacity of a widget dependent on the scroll position. Is it possible to retrieve the offset of a specific index tagged with AutoScrollTag
so I don't have to calculate the position myself? It seems like this feature must be already implemented in the AutoScrollController and would just be needed to make public.
Thanks in advance.
Benjamin!
It is throwing this error.
_lifecycleState != _ElementLifecycle.defunct
is not true
Hi there,
Nice plugin 👏
I would like to scroll to an item and use an offset to be more precise.
In my case I have a nice-looking padding on my scroll container 👍
But when I scrollToIndex
I don't have a way to ask him to scroll 20px before the item, making it looking a bit stuck on the left :
Is there a way or how would you do it if we have to implement it (I can help)
Thanks !
i got this error :
Cannot get size from a render object that has been marked dirty for layout.
any idea why ?
thanks
i try
_scrollController.scrollToIndex(currentIndex + addCount,
duration: Duration.zero,
preferPosition: AutoScrollPosition.begin);
but i does not work
I have a list with 36 000 records. When I am at the top of the list and I want to scroll to index 30 000 It takes a lot of time to complete. Setting the duration to Duration(microseconds:1) does not fix this.
It would be very useful for me to be able to check if a widget wrapped with an AutoScrollTag
is currently scrolled to the top of the screen. Can this be achieved with the current implementation?
I use a CustomScrollView in my app with groups of items - each one with a header.
The headers are wrapped with an AutoScrollTag
widget. When tapped - the headers are scrolled to the top of the screen.
I want to have a different behavior when the header is tapped according to its scroll position:
There's only a scrollToIndex() method. To have an inmediate scroll, I thought I could use duration: Duration.zero, but it launches a Failed assertion: line 216 pos 12: 'duration > Duration.zero': is not true.
So may you offer a jumpToIndex() method?
Thanks a lot!
Currently, the highlight color appears behind the child widget of AutoScrollTag
.
So if the said widget has a background color, it will cover the highlight color.
Here is an example where the highlight color is red. We can barely see it at the edges.
Is there any way for the highlight to be overlaid on top of the child widget?
Thank you.
I am planning to return current index when user pop the navigation. Is it possible?
For example, my screen is currently showing index 3 out of 15, when i scroll down the list...and lets say I am at index 6.. when i pop and come back to the screen, i want to maintain the last scrollable position which is index 6.
I have also implemented endless scrolling with this package, so the height of the listview will always increase and each item has dynamic height.
The error I get is below
right now I have a CustomScrollView, with multiple AutoScrollTags with SliverStickyHeaders inside of them from the flutter_sticky_header plugin
════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building DecoratedBoxTransition(animation: kAlwaysDismissedAnimation➩DecorationTween(BoxDecoration → BoxDecoration)➩BoxDecoration, state: _AnimatedState#59212):
A RenderViewport expected a child of type RenderSliver but received a child of type RenderDecoratedBox.
RenderObjects expect specific types of children because they coordinate with their children during layout and paint. For example, a RenderSliver cannot be the child of a RenderBox because a RenderSliver does not understand the RenderBox layout protocol.
The RenderViewport that expected a RenderSliver child was created by: Viewport ← IgnorePointer-[GlobalKey#77f73] ← Semantics ← _PointerListener ← Listener ← _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#ee4d1] ← _PointerListener ← Listener ← _ScrollableScope ← _ScrollSemantics-[GlobalKey#be6c5] ← RepaintBoundary ← ⋯
The RenderDecoratedBox that did not match the expected child type was created by: DecoratedBox ← DecoratedBoxTransition ← AutoScrollTag-[<0>] ← ExpandableTile ← Viewport ← IgnorePointer-[GlobalKey#77f73] ← Semantics ← _PointerListener ← Listener ← _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#ee4d1] ← _PointerListener ← ⋯
The relevant error-causing widget was
AutoScrollTag-[<0>]
lib\…\expandableTile\expandableTile.dart:51
When the exception was thrown, this was the stack
#0 ContainerRenderObjectMixin.debugValidateChild.<anonymous closure>
package:flutter/…/rendering/object.dart:3037
#1 ContainerRenderObjectMixin.debugValidateChild
package:flutter/…/rendering/object.dart:3064
#2 MultiChildRenderObjectElement.insertChildRenderObject
package:flutter/…/widgets/framework.dart:5808
#3 RenderObjectElement.attachRenderObject
package:flutter/…/widgets/framework.dart:5591
#4 RenderObjectElement.mount
package:flutter/…/widgets/framework.dart:5331
...
════════════════════════════════════════════════════════════════════════════════
flutter doctor results are all green
In the example, there is a counter that tracks if the counter is greater than the number of items in the list and if so, it sets the counter to 0 and attempts to scroll to the 0th index. However, when I'm implementing this, it tries to keep scrolling to the bottom. Am I missing something?
Can you please help, How can Use scroll_to_index list inside a list?
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: ListView(
shrinkWrap: true,
children: [
Container(
color: Colors.amber,
height: 40,
),
ListView.builder(
shrinkWrap: true,
controller: controller,
itemCount: 100,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (c, i) => AutoScrollTag(
key: ValueKey(i),
controller: controller,
index: i,
child: Container(
height: 200,
color: Colors.red,
margin: EdgeInsets.all(16),
),
)),
],
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
As title . I can't make it work with SliverAppBar it's not collapse with it
I have a list with hundreds of images, it takes a good few seconds to jump to a specific image at the bottom so I wonder if we can add an option to skip the scroll animation.
I found this issue with lists with many items (long ones).
In this case, when I scroll to some item close to the bottom, it doesn't matter what duration I set via method - it still takes a looong time to scroll, which is definitely more than my duration.
ScrollToIndex does not work if I put a widget wrapped with an AutomaticKeepAlive widget as a child of the AutoScrollTag widget.
What is the correct way, if any, to achieve this?
E/flutter ( 6337): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: 'package:scroll_to_index/scroll_to_index.dart': Failed assertion: line 332 pos 14: '(offsetToLastState?.offset ?? 0) >= 0': ERROR: %%%%%%%%%%%%%%: 3, 0, 1.0, RevealedOffset(offset: -252.0, rect: Rect.fromLTRB(20.0, 260.0, 340.0, 414.0)), 0
E/flutter ( 6337): #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:40:39)
E/flutter ( 6337): #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
E/flutter ( 6337): #2 _SimpleAutoScrollController&ScrollController&AutoScrollControllerMixin._forecastMoveUnit (package:scroll_to_index/scroll_to_index.dart:332:14)
E/flutter ( 6337): #3 _SimpleAutoScrollController&ScrollController&AutoScrollControllerMixin._scrollToIndex (package:scroll_to_index/scroll_to_index.dart:251:28)
E/flutter ( 6337): <asynchronous suspension>
E/flutter ( 6337): #4 _SimpleAutoScrollController&ScrollController&AutoScrollControllerMixin.scrollToIndex.<anonymous closure> (package:scroll_to_index/scroll_to_index.dart:195:27)
E/flutter ( 6337): #5 co (package:scroll_to_index/util.dart:37:26)
E/flutter ( 6337): <asynchronous suspension>
E/flutter ( 6337): #6 _SimpleAutoScrollController&ScrollController&AutoScrollControllerMixin.scrollToIndex (package:scroll_to_index/scroll_to_index.dart:195:12)
E/flutter ( 6337): <asynchronous suspension>
E/flutter ( 6337): #7 DemandWidgetApp.getDemandJsonData.<anonymous closure> (package:mer_meta/demandVsSupply.dart:1897:28)
E/flutter ( 6337): #8 State.setState (package:flutter/src/widgets/framework.dart:1127:30)
E/flutter ( 6337): #9 DemandWidgetApp.getDemandJsonData (package:mer_meta/demandVsSupply.dart:1868:5)
E/flutter ( 6337): #10 _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:77:64)
E/flutter ( 6337): #11 _rootRunUnary (dart:async/zone.dart:1132:38)
E/flutter ( 6337): #12 _CustomZone.runUnary (dart:async/zone.dart:1029:19)
E/flutter ( 6337): #13 _FutureListener.handleValue (dart:async/future_impl.dart:126:18)
E/flutter ( 6337): #14 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:639:45)
E/flutter ( 6337): #15 Future._propagateToListeners (dart:async/future_impl.dart:668:32)
E/flutter ( 6337): #16 Future._complete (dart:async/future_impl.dart:473:7)
E/flutter ( 6337): #17 _SyncCompleter.complete (dart:async/future_impl.dart:51:12)
E/flutter ( 6337): #18 _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:28:18)
E/flutter ( 6337): #19 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:294:13)
E/flutter ( 6337): #20 BusinessLogic.methodGetDynamic (package:mer_meta/businessLogic.dart)
E/flutter ( 6337): #21 _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:77:64)
E/flutter ( 6337): #22 _rootRunUnary (dart:async/zone.dart:1132:38)
E/flutter ( 6337): #23 _CustomZone.runUnary (dart:async/zone.dart:1029:19)
E/flutter ( 6337): #24 _FutureListener.handleValue (dart:async/future_impl.dart:126:18)
E/flutter ( 6337): #25 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:639:45)
E/flutter ( 6337): #26 Future._propagateToListeners (dart:async/future_impl.dart:668:32)
E/flutter ( 6337): #27 Future._complete (dart:async/future_impl.dart:473:7)
E/flutter ( 6337): #28 _SyncCompleter.complete (dart:async/future_impl.dart:51:12)
E/flutter ( 6337): #29 _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:28:18)
E/flutter ( 6337): #30 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:294:13)
E/flutter ( 6337): #31 _withClient (package:http/http.dart)
E/flutter ( 6337): #32 _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:77:64)
E/flutter ( 6337): #33 _rootRunUnary (dart:async/zone.dart:1132:38)
E/flutter ( 6337): #34 _CustomZone.runUnary (dart:async/zone.dart:1029:19)
E/flutter ( 6337): #35 _FutureListener.handleValue (dart:async/future_impl.dart:126:18)
E/flutter ( 6337): #36 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:639:45)
E/flutter ( 6337): #37 Future._propagateToListeners (dart:async/future_impl.dart:668:32)
E/flutter ( 6337): #38 Future._completeWithValue (dart:async/future_impl.dart:483:5)
E/flutter ( 6337): #39 Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:513:7)
E/flutter ( 6337): #40 _rootRun (dart:async/zone.dart:1124:13)
E/flutter ( 6337): #41 _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter ( 6337): #42 _CustomZone.runGuarded (dart:async/zone.dart:923:7)
E/flutter ( 6337): #43 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:963:23)
E/flutter ( 6337): #44 _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
E/flutter ( 6337): #45 _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
E/flutter ( 6337):
I modified the example a bit to reproduce the issue.
//Copyright (C) 2019 Potix Corporation. All Rights Reserved.
//History: Tue Apr 24 09:29 CST 2019
// Author: Jerry Chen
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: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: ListView(
shrinkWrap: true,
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),
);
}
this case is for some reason that scrolling to a index with the empty tagMap
.
part of stack trace:
E/flutter ( 2392): Receiver: null
E/flutter ( 2392): Tried calling: offset
E/flutter ( 2392): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
E/flutter ( 2392): #1 AutoScrollControllerMixin._forecastMoveUnit (package:scroll_to_index/scroll_to_index.dart:329:61)
E/flutter ( 2392): #2 AutoScrollControllerMixin._scrollToIndex (package:scroll_to_index/scroll_to_index.dart:251:28)
E/flutter ( 2392): <asynchronous suspension>
E/flutter ( 2392): #3 AutoScrollControllerMixin.scrollToIndex.<anonymous closure> (package:scroll_to_index/scroll_to_index.dart:195:27)
E/flutter ( 2392): #4 co (package:scroll_to_index/util.dart:37:26)
E/flutter ( 2392): #5 AutoScrollControllerMixin.scrollToIndex (package:scroll_to_index/scroll_to_index.dart:195:12)
While build app, I notice this warning:
[!] Your app isn't using AndroidX.
To avoid potential build failures, you can quickly migrate your app by following the steps on https://goo.gl/CP92wY.
So, if it's possible, could you please migrate sample app to AndroidX?
Thanks.
Having a big list of items with dynamic height, sometimes the scrolling animation takes way too long. is there any way too speed it up?
Scroll to index works perfect, thanks, but when there are a lot of records (100+) it scrolls quite long time even if I set duration 1ms, could you please create an option like jump to index, to appear at a needed index fast.
I'm getting the following error.
In my case:
The error happens occasionally.
After the error, isAutoScrolling does not return to true unless another scrollToIndex is requested.
Any ideas?
I haven't been able to produce a reasonably sized reproduction example yet. Any ideas what the problem may be?
Thanks in advance.
E/flutter (12779): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: 'package:scroll_to_index/scroll_to_index.dart': Failed assertion: line 339 pos 14: '(offsetToLastState?.offset ?? 0) >= 0': ERROR: %%%%%%%%%%%%%%: 15, 0, 1.0, RevealedOffset(offset: -408.8262626669658, rect: Rect.fromLTRB(NaN, NaN, NaN, NaN)), 0,1,4,6,8,10,12,14,17,19,21,24,26,28,30,31,32,33,34,35,36,37,38,39,40
E/flutter (12779): #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
E/flutter (12779): #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
E/flutter (12779): #2 AutoScrollControllerMixin._forecastMoveUnit (package:scroll_to_index/scroll_to_index.dart:339:14)
E/flutter (12779): #3 AutoScrollControllerMixin._scrollToIndex (package:scroll_to_index/scroll_to_index.dart:252:28)
E/flutter (12779): <asynchronous suspension>
E/flutter (12779): #4 AutoScrollControllerMixin.scrollToIndex.<anonymous closure> (package:scroll_to_index/scroll_to_index.dart:196:27)
E/flutter (12779): #5 co (package:scroll_to_index/util.dart:37:26)
E/flutter (12779): #6 AutoScrollControllerMixin.scrollToIndex (package:scroll_to_index/scroll_to_index.dart:196:12)
I've just implemented a sample Flutter app (https://github.com/eggzotic/scroll_to_index_sample) with this and am loving it - also managed to use Stateless Widgets throughout, with a little help from Provider package.
Problem: how to "scroll back/forward X (e.g. X=15) rows", if the user has already manually scrolled (using their finger!) so that the visible rows are no longer tracked by the controller? Can we reverse map from the controller current position (pixels) to the row-number?
When I try to call this code, controller.scrollToIndex(2);
it throws me this error,
[VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: NoSuchMethodError: The method '_subFromInteger' was called on null.
Receiver: null
Tried calling: _subFromInteger(2)
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 int.- (dart:core-patch/integers.dart:13:38)
#2 AutoScrollControllerMixin._getNearestIndex (package:scroll_to_index/scroll_to_index.dart:357:19)
#3 AutoScrollControllerMixin._scrollToIndex (package:scroll_to_index/scroll_to_index.dart:251:25)
<asynchronous suspension>
#4 AutoScrollControllerMixin.scrollToIndex.<anonymous closure> (package:scroll_to_index/scroll_to_index.dart:196:27)
#5 co (package:scroll_to_index/util.dart:37:26)
#6 AutoScrollControllerMixin.scrollToIndex (package:scroll_to_index/scroll_to_index.dart:196:12)
#7 _ChatScreenState.item.<anonymous closure> (package:chat_pls/ui/chat/chat_screen.dart:382:30)
#8 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:993:19)
#9 _InkResponseS<…>
I have a custom widget that builds a CustomScrollView
with form fields, with each of the form fields wrapped in AutoScrollTag
. This works well on its own, when I navigate to a Route
that has this custom widget as its child
- I can scroll to any of the form fields and highlight them.
I have a use case where a Route
has a SingleChildScrollView
as its child, with a header followed by my custom widget. For this page to scroll as expected, the CustomScrollView
in my custom widget is using physics: NeverScrollableScrollPhysics()
and shrinkWrap: true
. The problem is, scrollToIndex()
no longer scrolls to the specified field in this scenario - the highlighting still works even though the field is not on the screen.
I've tried assigning an AutoScrollController
to the SingleChildScrollView
and using the same controller with the AutoScrollTag
widgets, but that didn't make a difference.
I also tried setting the parentController
of the AutoScrollController
assigned to the CustomScrollView
to that of the SingleChildScrollView
, but that also didn't make a difference.
What is the correct way, if any, to achieve this?
I have a ModalBottomSheet with a single TextFormField and a button, and the input field gets highlighted when I tap the button. The problem is that the keyboard disappears when I call highlight().
I placed lots of breakpoints to try and understand why, and this is what I found:
After this line of code within your library is reached: await catchAnimationCancel(_controller.animateTo(1.0, duration: scrollAnimationDuration));
Flutter will unmount all inactive elements (as a result of setState
being called on the previous line), which for some reason I cannot explain includes my TextFormField as well. In turn, this triggers _closeInputConnectionIfNeeded()
within EditableTextState
, which then hides the keyboard because there are no active InputConnections left.
If I replace the call to highlight()
with a call to setState()
, the keyboard no longer disappears even though the UI is rebuilt, which means that it's something within your library's code that causes this.
Thanj you for this library ...but the scroll controller does not scroll to items outside the viewport
Thank you so much for this wonderful library. It has been a lifesaver and the highlight feature is exceptional!
Is there a way to cancel in flight scrolls? Because scrollToIndex is asynchronous, sometimes too many scrolls get queued up.
Ideally there's a way to get a list of active scrolls and then cancel them.
On a side note, isAutoScrolling
does not always return the correct value when multiple scrollToIndex
are called.
I'm happy to dig a bit more in depth and make a PR if you're available for answering some ScrollPosition questions. I've done a bit of research and have some experience here thanks to some synchronizing scroll work.
Highlight but not scrolling to bottom items which are not visible.
I have
SingleChildScollView(
child: ListView.generate( // works with this
child : ListView.generate( /// but not this
)
)
)
PS : I have added scrollcontroller to singlechildscrollview
I read other issues but its not solving my problem
Even if I go to that bottom item and try it scrolls back to top area where it becomes invisible
[ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: 'package:scroll_to_index/scroll_to_index.dart': Failed assertion: line 381 pos 14: '(offsetToLastState?.offset ?? 0) >= 0': ERROR: %%%%%%%%%%%%%%: 270, 235, 1.0, RevealedOffset(offset: -610.0, rect: Rect.fromLTRB(404.5, 640.0, 799.0, 672.0)), 256,257,258,259,260,261,337,338,339,340,341,342,277,278,279,345,346,347,311,312,313,314,315,316,348,349,1597,238,239,240,235,236,237,241,242,243,308,309,310,244,245,246,326,327,328,343,344,1596,331,332,333,274,275,276,320,321,322,305,306,307
I'm not quite sure why it's failed.
Is there any way to get current index on scrolling?
I'm able to index and highlight a list item just fine, but it won't scroll to that spot.
Full main.dart code:
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 {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Scroll To Index Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
static const maxCount = 100;
final random = math.Random();
final scrollDirection = Axis.vertical;
AutoScrollController asc;
int index;
List<int> list;
@override
void initState() {
super.initState();
asc = AutoScrollController(
viewportBoundaryGetter: () =>
Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom),
axis: scrollDirection);
/* this.list = List.generate(maxCount,
(index) => <int>[index, (1000 * random.nextDouble()).toInt()]); */
this.list = List.generate(100, (int i) {
return i;
});
//for (int i in this.list) print(i);
}
Future _scrollToIndex(int scrollindex) async {
//uncommenting the next line, (setting state) prevents yellow hightlight from showing up
// if (this.mounted) setState(() {});
// doesn't work
/* await asc.scrollToIndex(scrollindex,
preferPosition: AutoScrollPosition.begin); */
//works just fine
asc.highlight(scrollindex);
}
Widget builditem(int i) {
this.index++;
// print(index);
return AutoScrollTag(
key: ValueKey(this.index),
controller: asc,
index: this.index,
highlightColor: Colors.yellow,
child: Container(
decoration: BoxDecoration(
border:
Border.all(width: 1.0, color: const Color(0xFFFFDFDFDF))),
//height: screenSize.height / 6.0,
padding: EdgeInsets.all(16.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
//Text(room.roomguid),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 10.0),
child: Row(children: <Widget>[
Expanded(
child: Text(
i.toString(),
style: TextStyle(fontSize: 22),
),
)
])),
Container(
padding: EdgeInsets.only(left: 10.0),
child: Row(children: <Widget>[
Expanded(
child: Text(
i.toString(),
style: TextStyle(fontSize: 22),
),
)
]))
]))
],
)));
}
@override
Widget build(BuildContext context) {
this.index = 0;
return Scaffold(
floatingActionButton: FloatingActionButton(
heroTag: "scroll to..",
onPressed: () {
_scrollToIndex(15);
},
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: this.list.map(builditem).toList(),
),
),
)
],
),
);
}
}
I have a long data list (about 3k+ or more), when use controller.scrollToIndex(), it took several seconds to finally scroll to the target item.
The animation duration was set to Duration(milliseconds: 1), and it doesn't seem helpful to reduce the time cost of scrolling animtion.
So is that possible to merely jump to the target item without any scrolling animation?
Is it possible to get index of the first visible item in ListView?
Thanks.
When wrapping items in AutoScrollTab
, what are the requirements for the values used as index?
Do they need to be in order of the elements on the screen?
I have a CustomScrollView
that contains multiple slivers with different heights. Do I need to use growing indexes according to the position in the view?
Thanks for this useful library!
Rebuilding the widget that is being highlighted cancels the highlight.
I have a use case where once the user tries to submit a form, all input fields should be validated and should display the corresponding error messages, and the first input field with an error should also be highlighted. This requires me to call setState()
as well as highlight()
once all input fields have been validated. This causes the highlighted widget to be rebuilt as well, which in turn cancels the highlight. Actually, because I call both of those functions at the same time, the highlight is not displayed at all.
Here is some sample code with 2 buttons, one of which calls setState()
1 second after the highlight is triggered, and one that calls them both at the same time:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final AutoScrollController controller = AutoScrollController();
final int index = 0;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: ListView(
controller: controller,
shrinkWrap: true,
children: <Widget>[
AutoScrollTag(
key: ValueKey(index),
controller: controller,
index: index,
highlightColor: Colors.redAccent,
child: Container(
height: 50,
decoration: BoxDecoration(
border: Border.all()
),
),
),
RaisedButton(
child: const Text("Highlight (setState later)"),
onPressed: () {
controller.highlight(index);
Future.delayed(const Duration(seconds: 1), () {
setState(() {});
});
},
),
RaisedButton(
child: const Text("Highlight (setState now)"),
onPressed: () {
controller.highlight(index);
setState(() {});
},
),
],
),
),
),
);
}
}
As the title suggests, the items that are created by the FutureBuilder
cannot be scrolled to correctly.
It's relatively useful if the item is complex and need more time to build.
Can you please check if the package can support it?
First of all, thanks for your work!
Is it possible to implement an additional method (for example .scrollToIndexIfNotVisible) that will scroll only if the item is not in viewport? Or maybe there is a way to do this already?
Thanks in advance.
in line 425 cast to RenderBox prevents to use it with RenderSliver
probably it could been placed as assert, but it works without.
final renderBox = ctx.findRenderObject();//as RenderBox;
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.