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);
Related
I need to get the whole list.builder height including the part that is out of the screen view
The List children vary in height
i used the GlobalKey method but it is giving me only the height of the list shown in the screen
I found this solution and it's working and give me the full list.builder height after scrolling event
but when adding more children to the list.builder by changing the state
this code doesn't work anymore
scrollController.addListener(() {
double? fullListViewHeight;
double fullListHeightHelper = listKey.currentContext!.size!.height +
scrollController.position.extentAfter;
fullListView ??= fullListHeightHelper;
}
listview.builder only build the item that shown to user, in order to get the height with GlobalKey method, you can use listView which build all item at the same time. If you don't know how pass your list to listView , see this example:
List yourList = [...];
_buildList(){
List<Widget> _children =yourList.map((e) => YourListItem()).toList();
return ListView(
key:yourKey,
children: _children,
);
}
it is giving me only the height of the list shown in the screen
yes.. thats correct. because listview not render all the children. see the documentation of listview:
The ListView.builder ...constructor is appropriate for list views with
a large (or infinite) number of children because the builder is called
only for those children that are actually visible.
to get exact height of all children is impossible. since when the widget child is scrolled out of view, the associated element subtree, states and render objects are destroyed.
I think you need to calculate it manually or make the children height is same for all.
To calculate it, you need to make each item the same height. Then,
To get the height of the ListView.builder you simply multiply the height of each item by the length of the ListView.builder.
I want to implement a dashboard that has 2 widgets: a menu panel and a panel where information is displayed.
I also want that if you click the top left button, the panel would collapse and the information panel would be 100% of the screen's width.
How can I resize a widget on button click?
Wrap you sidebar with an AnimatedContainer. Then, set the width property on that container to width: isExpanded ? 200 : 0, where isExpanded is a bool that specifies whether or not the sidebar should be expanded, and 200 is the width that you want the sidebar to be when expanded.
To toggle the sidebar to be expanded or not, simply call this:
setState(() { isExpanded = !isExpanded; });
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 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();
}
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);
});
}
}