How to add specific actions to ListView when user drags to its start or end (when the curvy blue lines appear)? - flutter

I'm curious is there an easy way to add such functionality to my Flutter ListViews?
For example, I would like to trigger some animation on another widget when the user drags "over the edge" on the ListView with all of it's items scrolled to the top or bottom, that is when the curvy blue line indicating that we're at the end of the list appears.
It obviously has an event firing up to show those lines anyway.

It's not hard actually, you can use a custom ScrollController with a listener:
declare it, then in initState put:
_myController = ScrollController();
_myController.addListener(_myScrollListener);
and the function itself can be something like this:
_myScrollListener(){
if (_myController.offset >= _controller.position.maxScrollExtent && !_myController.position.outOfRange) {
print("List end");
}
if (_myController.offset <= _controller.position.minScrollExtent && !_myController.position.outOfRange) {
print("List top");
}
Use the controller with your ListView, add what you need to the listener.

Related

could we detect if we reach the top list or bottom using ScrollablePositionedList.builder instead of ListView.builder

ok i decided to use
ScrollablePositionedList.builder
https://pub.dev/packages/scrollable_positioned_list
instead of ListView.builderfor more controlling of the index navigation ..
we know that ScrollablePositionedList.builder use ItemScrollController() instead of ScrollController()
using ScrollController() we can do the following to detect if we reach the top list or bottom
ScrollController scrollController= ScrollController();
scrollController.addListener(() {
if(scrollController.position.atEdge){
if (scrollController.position.pixels == 0) {
///we arrive to the end
}
}else{
///we arrive to the top
}
}
});
but how could i do the same with using ScrollablePositionedList.builder that use ItemScrollController()
so i tried to do this
ItemScrollController scrollController = ItemScrollController();
final listener = ItemPositionsListener.create();
listener.itemPositions.addListener(() {
listener.itemPositions.value // here all what i get .. i cannot see any
position.atEdge or pixels like normal ScrollController
});
really does it not support the detection of top list or bottom or something went wrong with me ?
thanks
You can check
if the value of itemPositionsListener.itemPositions.value.first.index is 0
to say it is on top. And to check
if the value of ${itemPositionsListener.itemPositions.value.last.index} = list.length - 1
to say it reaches the bottom.
itemPositionsListener.itemPositions.addListener(() {
print(
'====current first ${itemPositionsListener.itemPositions.value.first.index}====');
print(
'====current last ${itemPositionsListener.itemPositions.value.last.index}====');
});

How to tap all items of a list or a grid in a Flutter widget test?

In my Flutter widget tests I want to tap all (or first n) items in a list or grid view.
I already came up with a solution and although it seems to work, it looks overly complicated to find the tap target again by key:
for (final element in find.byType(ListTile).evaluate()) {
await tester.tap(find.byKey(element.widget.key!));
}
Is there a more elegant way to do it?
You can tap at a certain location on the widget:
e.g. tapping at center of the widget
for (final element in find.byType(ListTile).evaluate()) {
await tester.tapAt(tester.getCenter(find.byWidget(element.widget)));
}

How to get present number of inserts/widgets in an overlay?

I have created flat buttons that hide or show widget by inserting and removing widget in overlay.
And if I keep pressing the hide button even after there are no more widgets left in overlay, I get
'_overlay != null': is not true.
Now, I wish to add a check in there but I didn't find any way to check present number of widgets in Overlay stack.
Any help?
void showOverlayEntry() {
createOverlayEntry();
Overlay.of(context).insert(overlayEntry);
}
void removeOverlayEntry() {
//wish to add a check here if there are no more inserts left to remove
overlayEntry.remove();
}

How to disable click events for entire children except one selected child in flutter?

Scenario: I have number of children in Listview.builder. For every children there is button which invokes TTS(text to speech). I wanted when any one of child is pressed rest all children should be in Listview.builder un-clickable till pressed child finishes its TTS.
I got answer from google like absorb pointer, ignore pointer to solve this.
But i dont know how to implement above scenario using these widgets.
Store a bool in the State of the class enclosing the ListView.builder. This bool should store if one of the children is currently doing its TTS. If it is true you should set all of the onPressed(or equivalent) method to null to prevent other taps from triggering an action. Ex:
bool hasBeenClicked = false;
void yourTTSMethod() {
setState(() {
hasBeenClicked = true;
});
... //Do normal method body
setState(() {
hasBeenClicked = true;
});
}
//In build method with each `List` item:
GestureDetector(//Just for sample, use whatever click detector you're currently using
onTap: hasBeenClicked ? null : yourTTSMethod
)

Is there a way in Flutter to catch the "start-moving" event in a Dismissible Widget?

I am using the Dismissible widget to be able to remove certain screens/widgets from a flutter app by swiping them up.
What I need to achieve is to blur the image once the user starts swiping/dismissing them but the widget only has the "onDismissed" callback, but does not offer a way to catch the swiping event.
Any alternatives?
You can achieve That using the GestureDetector widget
// This is the sample
GestureDetector(onPanUpdate: (details) {
if (details.delta.dx > 0) {
// swiping in right direction
}
});
You can check there are many events that you can trigger like onHorizontalDragUpdate, and many more you can check out.