I have the following function
buildVideos() {
var videos = super.getVideos();
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
for (var video in videos) Container(child: Text(video["thumbnail"]))
],
),
);
}
}
The above code gives me the overflow error (yellow strip). But When I change the scrollDirection to Axis.horizontal, it works fine. I have tried wrapping it in Expanded widget with no success.
Can somebody help me?
Related
Can anyone clarify for me what I have shown in the 'image' attached is achievable in flutter? if yes, how? explaining the image is a bit hard.
I am new to flutter and trying to nest some scrollable views inside each other.
at first I tried to achieve this by nesting simple scrollable row and columns inside each other but faced some errors and exceptions (unbound height and width).
I searched and found out it is better to use 'CustomScrollView' for nesting lists in each other. tried it but haven't achieved what I want yet.
Any help/hint on how to achieve this would be much appreciated.
Nested Scroll Views
This is definitely possible, and you could use an approach like below, which is inspired by another question on stack overflow. I recommend reading that for better clarification -- here.
Edit: Wrapping the Row widget in a SingleChildScrollView would make the entire page scrollable.
body: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: ListView.builder(
scrollDirection: Axis.vertical,
itemCount: X,
itemBuilder: (BuildContext context, int index) => ...
),
),
Expanded(
child: ListView.builder(
scrollDirection: Axis.vertical,
itemCount: Y,
itemBuilder: (BuildContext context, int index) => ...
),
),
],
);
If this doesn't help, I'd suggest finding flutter repositories of e.g. Netflix clones or other existing apps known to have scroll views inside a list view.
#bragi, thanks for the answer,
I followed what you suggested and after some trial and error, I finally got it working.
But in terms of efficiency and how the application will respond/render I am not sure if this was the best way to do it:
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
// mainAxisSize: MainAxisSize.min,
children: [
makeColumn(),
makeColumn(),
makeColumn(),
makeColumn(),
makeColumn(),
],
),
),
Widget makeColumn() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Container(
width: 150,
height: 150,
color: Colors.green,
),
SizedBox(
width: 150,
height: 500,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [
Container(), ....
For some reason, the Expanded widget did not work so I had to wrap my second column with SizedBox!
I am trying to create scrollable row that does not automatically center its items.
As you can see I have a row (that is scrollable via a SingleChildScrollView). However, the items are automatically centered by the SingleChildScrollView:
I want to be able to customize the alignment of the items to be either on the start or end. My code looks like this:
Widget buildHorizontalRow(List entries) {
var list = <Widget>[];
for (var entry in entries) {
list.add(Text(
entry.name,
));
}
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: list,
),
);
}
Note that when I remove the SingleChildScrollView completely, the items start on the left as expected. How do I make them start on the left and scrollable?
Update #1:
The parents of this row look like this:
Padding(
padding: const EdgeInsets.only(
left: 16.0, right: 16.0, bottom: 8.0, top: 8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [....
PS: Also please note that I do not want to use a ListView.
While using Column the default is crossAxisAlignment: CrossAxisAlignment.center,, using CrossAxisAlignment.start, solves the issue.
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
You can try this, it working from my side.
Widget buildHorizontalRow(List entries) {
var list = <Widget>[];
for (var entry in entries) {
list.add(Text(
entry.name,
));
}
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [Row(children:list),Expanded(child:Container(),),]
),
);
}
I am trying to get the layout as in the gif below but could not get any resource to continue with. There are two rows with multiple columns and is scrollable. How can I achieve such layout?
As your question says, you follow this approach, and it is not containing multiple columns, items are having different width. This snippet will work fine.
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Column(
children: [
Row(
key: const ValueKey("row1"),
children: _items(),
),
Row(
key: const ValueKey("row2"),
children: _items(),
),
],
),
),
You can achieve this by SingleChildScrolView widget with axis : horizontal and that listitem will be created using FilterChip widget.
like this :
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Wrap(
spacing: 10.0,
runSpacing: 5.0,
children: [...generateTags()],
),
),
generateTags(){
return _keywords.map((e) => FilterChip(label : e)).toList();
}
var _keywords =["hello" , "hi" ,"words 1" , "word 2"];
I need to build a page with lists of objects that are grouped in a single line. This needs to be scrolled both vertically (to show more groups) and horizontally (to show groups children).
The vertical and horizontal scroll needs to move the items altogether.
Something like this: https://gph.is/g/46gjW0q
I'm doing this with this code:
Widget _buildGroups() {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
width: 2000,
child: ListView.builder(
scrollDirection: Axis.vertical,
itemCount: boardData.length,
itemBuilder: (context, index) {
return Row(children: _buildSingleGroup(index));
},
),
),
);
}
List<Widget> _buildSingleGroup(int groupIndex) {
return List.generate(...);
}
I need this to be horizontally dynamic but here, as you can see, I need to set a width cause otherwise an error occurs:
══════════════════ Exception caught by rendering library ═════════════════════
The following assertion was thrown during performResize()
Vertical viewport was given unbounded width.
Viewports expand in the cross axis to fill their container and constrain their
children to match their extent in the cross axis. In this case, a vertical
viewport was given an unlimited amount of horizontal space in which to expand.
I tried to set "shrinkWrap: true" in the ListView but the result gives another error:
Failed assertion: line 1629 pos 16: 'constraints.hasBoundedWidth': is not true.
So how do you do this with a dynamical ListView width?
The error happens because when ListView tries to get height from its parent to fill the entire height, the parent returns infinity height because SingleChildScrollView doesn't have fixed container height value. To fix that issue you need to limit the height value. For example, I used SizedBox to specify height for ListView.
The following code works for me.
SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 120, // <-- you should put some value here
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: items.length,
itemBuilder: (context, index) {
return Text('it works');
},
),
),
],
),
);
Please can you explain your guess about the objects size?
I have a solution, but in my solution , flutter will build all objects (In both axes) for first frame. And build again any setState in the three. So its not good solition.
Last scroll offset horizontally
and
But I'll explain anyway.
///
class BothAxisScroll extends StatefulWidget {
#override
_BothAxisScrollState createState() => _BothAxisScrollState();
}
class _BothAxisScrollState extends State<BothAxisScroll> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.all(30),
child: Container(
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: _build(),
),
),
),
),
),
);
}
}
List<Widget> _build() {
return List.generate(
20,
(index) => Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: _buildSingleGroup(index),
));
}
List<Widget> _buildSingleGroup(int _index) {
return List.generate(
Random().nextInt(20),
(index) {
print('BUILD: $_index');
return Container(
padding: const EdgeInsets.all(15), child: Text("$_index-$index"));
},
);
}
and result in first frame :
So I am working on app which has a chat screen, So I finished with most of the functionality but I noticed that listView isn't resizing when the keyboard shows but the message input does move up.
As you can see Input does move up but not the ListView so I tried to move the ListViewto bottom when the keyboard shows up by moving it to bottom using ScrollController but it also didn't work
Here's my current implementation:
chat_view.dart
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
MessageListView(),
ChatInputToolbar(),
]
)
);
message_list_view.dart
Flexible(
child: ListView.builder(
controller: scrollController,
shrinkWrap: true,
reverse: false,
itemCount: messages.length,
itemBuilder: (context, i) {}
)
);
I think that you should wrap your container into SingleChildScrollView, maybe that will help you. I would write something like this:
return SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
MessageListView(),
ChatInputToolbar(),
]
),)
);
Use Scaffold widget at the start of your widget tree, it solved my problem
In your Scaffold, set resizeToAvoidBottomPadding property to false then try:
resizeToAvoidBottomInset : false,