I mean in both axis, horizontal and vertical.
I tried nesting two ListView.builder but they don't scroll together as I would like.
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: Drawer(),
appBar: AppBar(),
body: Container(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, x) {
return Container(
height: 50,
width: 50,
child: ListView.builder(
itemBuilder: (context, y) {
return Container(
height: 100, child: Text("${y.toString()}"));
},
),
);
}),
));
}
}
Possible solutions I have in mind:
Make the ListView.builders scroll together. But I think that solution may not be efficient performance wise, since flutter still treating each column as an individual scroller
Create a finite ListView.builder and rebuild it as necessary to make the illusion it is infinite. But that may add unnecessary complexity to the project.
Add NeverScrollableScrollPhysics on vertical axis and perform the scroll with another Widget. I failed attempting that. That method just worked for me if the list is finite.
Is there any widget appropriated to that application that I could be maybe missing?
Is there any other better approach to create something like that?
Two dimensional scrolling is supported by DataTable (try the Flutter Gallery "Data tables" demo) and Table. Maybe try building a schedule widget based on on of those.
You can use wrap DataTable inside two SingleChildScrollView widgets to achieve bidirectional scrolling..
By using something like this
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
dataRowHeight: 50,
dividerThickness: 5,
horizontalMargin: 15,
columnSpacing: 13,
showBottomBorder: true,
headingRowColor: MaterialStateProperty.all<Color>(
Colors.blueGrey[100]),
columns: [
DataColumn(
label: Text(
"Module Name",
style: TextStyle(
// fontStyle: FontStyle.italic,
fontWeight: FontWeight.w600,
fontSize: 14,
color: Theme.of(context).highlightColor,
),
),
numeric: false,
),
],
rows: data
.map((details) => DataRow(
cells: [
DataCell(
Text(
details.name,
),
),
//list of cells: remenber the number of DataColumn and DataCell should be same
],
))
.toList()),
),
);
To fetch data from internet you can wrap the first SingleChildScrollView with FutureBuilder
PS: here data is list of modules data fetch from internet,
just for example I have added only one DataColumn you can add as needed
Related
CustomScrollView(
scrollDirection: Axis.horizontal,
slivers: [
SliverToBoxAdapter(
child: Container(height: 600, width: 400, color: Colors.red),
),
// HERE I NEED MULTIPLE SliverLists VERTICALLY - BEGIN
Column(
children:[
SliverList(
delegate: SliverChildBuilderDelegate(
(_, index) => SomeExpensiveWidget(index),
childCount: 10000,
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(_, index) => SomeCustomRowWidget(index),
childCount: 10000,
),
),
]
),
// THIS DOESNT WORK - END
SliverToBoxAdapter(
child: Container(height: 600, width: 400, color: Colors.red),
),
],
),
I have a CustomScrollView and it is scrolling horizontally. Due to some reason I need to have multiple SliverList in a Column widget. I am trying to create a 2D grid and I can't use SliverGrid because my widgets inside SomeCustomRowWidget only works when they are in a Row (elements in row shrink and get bigger according to some condition). I am trying to have multiple SliverList in a Column to give the illusion of a grid but so far its not working because Column widget works with normal widgets. There is no SliverColumn or something like that. How may I position SliverLists as if they are in a Column?
there is a widget let you put any widget as slivers
wrap the widgets you want to show with SliverToBoxAdapter like this
SliverToBoxAdapter(
child: YourWidget(),
),
it will just let adapt your other widgets to the slivers family.
I'm developing a table at Flatter.
In order to process selection/unselection for each row of the table, I would like to develop a Checkbox for the header of the table and all rows.
Then, I found the showCheckboxColumn option in the DataTable widget and applied it with pleasure.
However, as shown in the picture below, the Checkbox was not applied at all, and I can't find the cause.
The DataTable widget I designed is written like the following code:
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.fromLTRB(24, 34, 24, 24),
child: Scrollbar(
trackVisibility: true,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Selected Delete',
),
SingleChildScrollView(
padding: EdgeInsets.only(top: 19),
scrollDirection: Axis.vertical,
child: DataTable(
showCheckboxColumn: true,
headingRowColor: MaterialStateProperty.all(Color(0xFFEEEEEE)),
rows: _getTableDatas(),
columns: _getTableHeaders(),
),
),
],
),
),
),
);
}
Is there any part of this code that I'm wrong about or I'm wrong about the concept of DataTable?
According to the docs,, You need to add showCheckboxColumn property to make the row selectable. Try adding and do let me know.
I'm trying to make a column with two children begin at a certain position on the screen. The 2nd child is a dynamic ListView where I do not want the number of children changing the position of the column.
How is this possible?
Just wrap your ListView with Expanded widget .
Example:
Column(
children: [
Expanded( //here
child: ListView.builder(
itemBuilder: (context, index) => Text('test $index'),
itemCount: 50, ),
),
Column(
children: [
Container(height: 100, color: Colors.yellow),
OutlinedButton(onPressed: (){}, child: Text('Test'),),
Text('Another Test')
]
)
],
),
I used a Listview.builder because I don't want to do it one by one. Just for the example
You can learn more about Expanded widget by watching this Official video or by visiting flutter.dev
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,
),
);
}
),
),
);
}
}
Im building an app that shows diets and also have a search bar to look for the diets.
I cant manage accomodate the search bar correctly like outside the gridviewer. heres the code of my view and how it actually looks. I dont want to be like another card
body: Container(
child: GridView.builder(
padding: EdgeInsets.all(15),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemCount: dietsForDisplay.length + 1,
itemBuilder: (BuildContext context, int index) {
if (diets.length == 0) {
return Container(
child: Padding(
padding: const EdgeInsets.all(60.0),
child: Text(
"No existen Dietas registradas por la nutriĆ³loga.",
style: TextStyle(
color: Color(0xFF002D53),
fontFamily: 'Montserrat',
fontSize: 25,
fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
);
} else {
return index == 0
? _searchBar()
: _listItem(
context,
index - 1,
);
}
}),
));
}
and the code for the searchBar and listItem are Cards
Wrap your material app inside a Safe Area Widget
https://api.flutter.dev/flutter/widgets/SafeArea-class.html
I would suggest you to wrap your Scaffold widget with SafeArea so that your appbar won't get obstructed due to the notch. If you would want to add a search bar in your Scaffold's body, I would suggest using a Column to place your search bar on the top and your GridView.builder() on the bottom. Here is how it looks like after my suggestions:
SafeArea(
child:Scaffold(
body: Column(
children: <Widget>[
//Search Bar here
Expanded(
child: //GridView.builder() here
);
],
),
),
);
*If you want that page to be scrollable then replace Column with ListView