Is it possible to dismiss dismissable programmatically? Not by swipe, but by let's say button click.
The only thing that comes in mind is imitating gesture event with a certain velocity, but this sounds horribly wrong.
How about considering an AnimatedList instead.
A scrolling container that animates items when they are inserted or removed.
This widget is similar to one created by ListView.builder.
Please try this.
key: Key(UniqueKey().toString()),
2nd Way
onDismissed: (DismissDirection direction) { dismissViewList(ObjecClass); }
And function is :
dismissViewList(ObjecClass) {
if (_personList.contains(ObjecClass)) {
//_personList is list of ObjecClass shown in ListView
setState(() {
_personList.remove(ObjecClass);
});
}
}
Related
I have a problem with a BottomNavigationBar. My app has two screens and one of them has a bottom sheet that doesn't hide on disposing of the first screen when I'm tapping on the icon of the second screen. BottomNavigationBar works normally and screens switch, but how to hide the bottom sheet of the first screen when shown the second screen I have no ideas. Could you help me solve that?
Calling:
void _showForm(int id) async {
showBottomSheet(
context: context,
elevation: 5,
builder: (context) => BottomSheetSwitch(_refreshJournals, id));
}
Closing (inside bottom sheet):
Navigator.of(context).pop();
P.S. I couldn't solve that problem, so I change showBottomSheet to showModalBottomSheet like that was in: how to set showModalBottomSheet to full height?
You can try to provide a key to the stateful widget of BottomSheet. And access that key's context just use the Navigator's pop method on tap or change of the screen. It might help you.
You can use it like
Navigator.of(key.currentContext).pop();
Else call the function of your BottomSheet using the key. Like as below
Declare GlobalKey with state in your currentWidget.
GloabalKey<BottomSheetWidgetState> closeKey = GloabalKey();
Declare one function closeBottomSheet in your bottomsheet widget state.
void closeBottomSheet(){ Navigator.of(conext).pop(); }
Call the function using the key.
closeKey.currentState.closeBottomSheet();
And done.
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)));
}
I have ListView.builder with horizontal scrolling (a custom top navigation bar). As I scroll to the right and left, the 'selectedIndex' is changing, but the UI inside this widget isn't showing this change in position. I'd like to 'Jump To' the selected index upon swiping.
Here's how my ListView is currently updating its index:
void onChanged(int index) {
pageController.jumpToPage(index);
setState(() {
this.selectedIndex = index;
});
}
How can I accomplish this? Any guidance would mean a lot.
Thanks, A.V.
You can calculate selected item offset by item width and height and then use
_gridViewController.jumpTo(calculatedOffset);
I am copying my question from here as it is the same question but for flutter
How do you know if your ListView has enough number of items so that it
can scroll?
For instance, If I have 5 items on my ListView all of it will be
displayed on a single screen. But if I have 7 or more, my ListView
begins to scroll. How do I know if my List can scroll
programmatically?
Thank you
I am adding the code I tried, in which I test if the controller is attached, to be able to get the position. I couldn't get the position because the controller is not attached until you actually scroll
Widget build(BuildContext context) {
_afterBuild();
ListView.builder(
controller: controller,
// ...
)
}
Future<void> _afterBuild () async {
if (controller.hasClients) {
print("controller.hasClients");
// here I would be able to get the position
} else {
print("controller.has no Clients");
}
}
Edit: For anyone coming here: The controller was not being attached because I had a condition under which to build the ListView
So I combined the comments with the accepted answer (which is actually the answer for the question) and solved it like this (with some pseudocode):
Widget build(BuildContext context) {
if (not loaded results from api) {
return Something()
} else {
Future(_afterBuild);
return ListView.builder(
controller: controller,
// ...
)
}
}
Future<void> _afterBuild () async {
if (controller.hasClients) {
if(controller.position.maxScrollExtent > 0){
print('it can be scrolled');
}
} else {
print("controller has no client");
}
}
Actually it's quite easy to do in Flutter. You should have a ScrollController attached to your ListView and then you can check the maxScrollExtent. If it's bigger than zero then your ListView can be scrolled. It also works for any scrolling view which uses ScrollController.
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
if(controller.position.maxScrollExtent > 0){
print('it can be scrolled');
}
});
}
Step 1 - Assign a GlobalKey
GlobalKey myKey= GlobalKey();
Step 2 - Assign key to ListView
ListView(
key: myKey,
...
)
Step 3 - In your function that checks if the ListView is scrollable, use the following code-
final RenderBox renderBoxRed = myKey.currentContext.findRenderObject();
final height = renderBoxRed.size.height; // find height of ListView
if (height > MediaQuery.of(context).size.height) { // checking if listview height is greater than page height
print("ListView is SCROLLABLE !!!");
}
I like where most of the rest of the answers are going, but they aren't getting the data the most succinctly or reliably. What you want to do is, yes, attach a ScrollController, and then look for the .position on that (which may throw if there's no single attached position). Then, ask the position for extentAfter and extentBefore, and you'll discover how much virtual view (in pixels) there is after and before the current visible portion. If those are 0, no scrolling. No need to figure out the size of the screen or the containers. Flutter already knows all that when it laid everything out!
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.