Flutter Horizontal ListView add lines under instead of infinite scroll - flutter

The purpose of the application is to show many buttons that the user must select. Unfortunately infinite scrolling is not a user friendly tool here and it would be preferred to not have the user make any more actions than necessary.
As such, I need the horizontal ListView to be within one screen and expand under, adding new rows. I've tried adding a SizedBox, but the ListView row is still infinite and goes off screen.
return new Scaffold(
appBar: AppBar(
title: Text("Test"),
),
body: SizedBox(
width: 300.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: _rowWidgets.toList() // these are just IconButtons
),
)
);
The number of items may vary and I cannot divide the list into sublists consistently on all screens.

It seems you need Wrap widget. Of course widget has no horizontal scrolling like in ListView. So you have to provide vertical scrolling to show a lot of buttons.
return Scaffold(
appBar: AppBar(
title: Text("Test"),
),
body: Center(
child: Container(
padding: EdgeInsets.all(16.0),
color: Colors.green,
width: 300.0,
child: Wrap(
spacing: 8.0, // gap between adjacent chips
runSpacing: 4.0, // gap between lines
children: List.generate(9, (i) => item(i.toString())).toList()
),
),
)
);

Related

how to use TabBar view inside scrollable widget in flutter

I have this design, The first section in the red box is fixed height size, and The second section is the dynamic height (ListviewBuilder) which changed the content based on the tabBar.
My question is How can I use the TabBar view inside the scrollable widget (custom scroll view/listview etc..)
the solution That I currently found is to use a customScrollView and use SliverFillRemaining like that
SliverFillRemaining(
child: TabBarView(
children: [],
),
),
but that adds extra white space at the bottom of the list and I can't remove it by
making hasScrollBody property false
You could probably achieve what you want with this kind of template :
Scaffold(
body: Column(
children: [
Container(
height: MediaQuery.of(context).size.height * .33,
child: Container(/* Content of the first section */),
),
Expanded(
child: DefaultTabController(
length: 2,
child: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Container(
height: 50,
child: TabBar(
tabs: [Text("Guest"), Text("Service")],
),
),
),
SliverFillRemaining(
child: TabBarView(
children: [
// Your ListView Builder here
],
),
),
],
),
),
),
],
),
);
Seeing the bit of code you posted, it is probably close to what you already have but after test it doesn't adds extra white space at the bottom.
If it continue to display the same behavior, adding a little more context could help us provide a more accurate answer.

Nested listviews scrolling behavior different when scrolled using drag vs scrollwheel

Flutter web.
When we scroll by dragging the mouse, parent scrolls even when child listview is under cursor. But while scrolling with mouse wheel or double finger swipe gesture on touchpads, the scroll behavior is different. The parent stops scrolling and child starts scrolling when child listview comes under cursor.
gif of example
You can try the following code.
var _container = Container(
height: 200,
color: Colors.blue,
margin: EdgeInsets.symmetric(vertical: 10),
);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("ListView")),
body: Padding(
padding: const EdgeInsets.all(40.0),
child: ListView( // parent ListView
children: <Widget>[
_container,
_container,
Container(
height: 200, // give it a fixed height constraint
color: Colors.teal,
// child ListView
child: ListView.builder(itemBuilder: (_, i) => ListTile(title: Text("Item ${i}"))),
),
_container,
_container,
_container,
],
),
),
);
}
What I want is for the mousewheel scroll to behave like dragging. How can I get that?

can't scroll after adding a transparent container

I have a PageView with Stack children. those Stack widgets contain transparent containers that controlls the opacity level relative to the scroll position.
the expense is that now I am unable to scroll what's in the background. what is the best way to add that layer and keep my backround scroll active.
Updating the Listview widget seems expensive as the opacity transion changes that is why I tried to keep it separate
I have something like this
Stack(children: [
Scaffold(
body: SafeArea(
child: Container(
color: Colors.white,
child: ListView..., // the listView I am trying to scroll
),
),
),
currIndex == 1 ? MainCardTransitionContainer() : Container(), // the layer with opacity
]),
Try IgnorePointer:
Stack(children: [
Scaffold(
body: SafeArea(
child: Container(
color: Colors.white,
child: ListView..., // the listView I am trying to scroll
),
),
),
currIndex == 1 ? IgnorePointer(ignoring: true, child:MainCardTransitionContainer(),) : Container(), // the layer with opacity
]),
Try this
Stack(children: [
currIndex == 1 ? MainCardTransitionContainer() : Container(), // the layer with opacity
Scaffold(
body: SafeArea(
child: Container(
color: Colors.white,
child: ListView..., // the listView I am trying to scroll
),
),
),
]),
It's because the top widget of stack is kept at background and last widget is placed in foreground.
In short keep background element at top of stack

Flutter Nested bottom sheet or slide up panel

What is the best way to build a "nested bottom sheet" which behaves like this:
https://dribbble.com/shots/14139422-Mobile-banking-app-interactions?
Do I have to use NestedScrollView or CustomScrollView, or a completely different approach?
Update :
This is my result using SlidingUpPanel, but I still have two problems:
When sliding up the panel, the green and red containers stay behind the panel and do not scroll out of view at the top.
In landscape mode the containers are higher than the device, so this approach does not work. I need the panel to be attached to the bottom of the containers, so it is only visible when scrolling down.
Code:
SafeArea(
child: Scaffold(
body: SlidingUpPanel(
minHeight: MediaQuery.of(context).size.height - 479,
maxHeight: MediaQuery.of(context).size.height - 79,
panel: SingleChildScrollView(
child: Column(
children: [Text('Sliding Panel')],
),
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
height: 100,
color: Colors.green,
),
Container(
height: 300,
color: Colors.red,
)
],
),
),
),
),
);
Result:
I believe there is a Widget for what you want to do, since there is a widget for everything in Flutter. here is the link of the package
NOTE : you can also set minimum height of the widget when collapsed in order to control how much of the widget you can show when it is collapsed.
And here is the demo :

Making a 2x2 grid in Flutter

I'm trying to create a 2x2 grid for displaying some info in cards. Disclaimer: I'm totally new to Dart and Flutter, so expect a lot of ignorance on the topic here.
These cards should have a fixed size, have an image, display some text... and be positioned from left to right, from top to bottom.
First, I tried to use the Flex widget, but it seems to only work horizontally or vertically. Therefore, my only solution was to use two Flexes, but only showing the second when the amount of elements is higher than 2 (which would only use one row).
Then, I tried using GridView, but it doesn't work in any possible way. It doesn't matter which example from the Internet I copy and paste to begin testing: they just won't show up in the screen unless they're the only thing that is shown in the app, with no other widget whatsoever. I still don't understand why that happens.
This is my current code:
First widgets in "home_page.dart":
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: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(padding: EdgeInsets.only(top: 30)),
Text(
'App test',
style: TextStyle(fontSize: 24),
),
EventsList(key: new Key('test')),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
The "EventList" part is a widget that should represent the grid functionality I explained before. This class gets some info from a service (which currently just sends some hardcoded info from a Future), and paints the given widgets ("Card" items, basically) into the EventList view:
class _EventsListState extends State<EventsList> {
#override
Widget build(BuildContext context) {
return FutureBuilder<List<Event>>(
future: new EventsService().getEventsForCoords(),
builder: (context, AsyncSnapshot<List<Event>> snapshot) {
if (snapshot.hasData) {
return Padding(
padding: EdgeInsets.only(left: 20, right: 20),
child: Flex(
direction: Axis.horizontal,
verticalDirection: VerticalDirection.down,
mainAxisAlignment: MainAxisAlignment.center,
children: generateProximityEventCards(snapshot.data),
));
} else {
return CircularProgressIndicator();
}
});
}
List<Card> generateProximityEventCards(List<Event> eventList) {
// Load Events from API
print(eventList);
// Render each card
return eventList.map((Event ev) {
return Card(
child: Padding(
padding: EdgeInsets.only(bottom: 15),
child: Column(
children: <Widget>[
Image(
fit: BoxFit.cover,
image: ev.imageUrl,
height: 100,
width: 150,
),
Padding(
child: Text(ev.name),
padding: EdgeInsets.only(left: 10, right: 10),
),
Padding(
child: Text(ev.address),
padding: EdgeInsets.only(left: 10, right: 10),
),
],
),
));
}).toList();
}
}
This is how it currently looks:
As I said before, I understand that the Flex widget can't really get that 2x2 grid look that I'm looking for, which would be something like this (done with Paint):
So, some questions:
How can I get a grid like that working? Have in mind that I want to have more stuff below that, so it cannot be an "infinite" grid, nor a full window grid.
Is it possible to perform some scrolling to the right in the container of that grid? So in case there are more than 4 elements, I can get to the other ones just scrolling with the finger to the right.
As you can see in the first image, the second example is bigger than the first. How to limit the Card's size?
Thank you a lot for your help!
The reason the gridview was not working is because you need to set the shrinkWrap property of theGridView to true, to make it take up as little space as possible. (by default, scrollable widgets like gridview and listview take up as much vertical space as possible, which gives you an error if you put that inside a column widget)
Try using the scrollable GridView.count widget like this and setting shrinkWrap to true:
...
GridView.count(
primary: false,
padding: /* You can add padding: */ You can add padding const EdgeInsets.all(20),
crossAxisCount: /* This makes it 2x2: */ 2,
shrinkWrap: true,
children: generateProximityEventCards(snapshot.data),
...
Is this what you exactly want?
do let me know so that I can update the code for you
import 'package:flutter/material.dart';
class List extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
title: Text('Inicio', style: TextStyle(color: Colors.black, fontSize: 18.0),),
),
body: GridView.count(
shrinkWrap: true,
crossAxisCount: 2,
children: List.generate(
50,//this is the total number of cards
(index){
return Container(
child: Card(
color: Colors.blue,
),
);
}
),
),
);
}
}