I am trying to have a vertical list of horizontal listviews. Currently the User Experience is really bad in that scrolling does sometimes not work. This is similar to like a youtube homepage or Spotify where you scroll down and each row is scrollable
Expanded(
flex: 5,
child: Container(
width: double.infinity,
height: 500,
child: ListView.builder(
shrinkWrap: true,
physics: ScrollPhysics(),
itemCount: skills.length,
itemBuilder: (context, index){
return CategoryHomeScreen(videosInSection: videoRecommended[skills[index]] ?? [], skill: skills[index]);
}),
),
),
The widget referred to in item builder
return Column(
children: [
Padding(
padding:
EdgeInsets.fromLTRB(HomeBrain.headingPaddingLeftSide, 0, 0, 0),
child: Text(
widget.skill,
style: Constants.subHeading,
)),
//these are horizontal scrollviews to see more videos
Container(
height: HomeBrain.videoHeightBox +
HomeBrain.sizeBetweenvideoAndSub +
HomeBrain.videoHeight -
HomeBrain.takeAwayFromContainerSizedOfVideoFram,
child: SizedBox(
height: 0,
width: double.infinity,
child: ListView.builder(
physics: ClampingScrollPhysics(),
scrollDirection: Axis.horizontal,
itemCount: widget.videosInSection.length,
itemBuilder: (context, int index) {
//passes over author, thumbnail url, thumbnail and video url so each tile is unique
return ScreenTile(
authorName: widget.videosInSection[index].userNameBy,
pathToThumbnail: widget.videosInSection[index].thumbNailUrl,
thumbnail: widget.videosInSection[index].thumbnail,
pathToVideo: widget.videosInSection[index].videoUrl,
profilePic: widget.videosInSection[index].profilePic,
videoBrain: widget.videosInSection[index],
);
},
),
),
),
],
);
you can do it this way. This is for demo purposes.
ListView.builder(
itemCount: 15,
itemBuilder: (_, i) {
return _horizontalListView();
},
),
Widget _horizontalListView() {
return SizedBox(
height: 120,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (_, __) => _buildBox(color: Colors.orange),
),
);
Widget _buildBox({required Color color}) => Container(margin: EdgeInsets.all(12), height: 100, width: 200, color: color);
Related
I want to have a horizontally scrollable container and inside it somewhere a ListView, which scrolls vertically:
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: ListView.builder(
shrinkWrap: true,
primary: false,
itemCount: 5,
itemBuilder: (context, index) {
return const SizedBox(
height: 10,
width: 10,
);
},
),
);
but I get this error: RenderBox was not laid out. I already put Expanded around everything imaginable. It has to be a SingleChildScrollView.
I need help.
Provide width on ListView, it will solve the issue.
LayoutBuilder( /// needed to be top level
builder: (context, constraints) => SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SizedBox(
width: constraints.maxWidth,
child: ListView.builder(
primary: false,
physics: ClampingScrollPhysics(),
itemCount: 5,
itemBuilder: (context, index) {
return const SizedBox(
height: 10,
width: 10,
);
},
),
),
),
);
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SizedBox(
width: MediaQuery.of(context).size.width, //you may get different way like LayoutBuilder on top level
child: ListView.builder(
primary: false,
physics: ClampingScrollPhysics(),
itemCount: 5,
itemBuilder: (context, index) {
return const SizedBox(
height: 10,
width: 10,
);
},
),
),
);
I need to scroll the whole screen, i am using (single child scroll view => stack => ListView.builder). but there is no scrolling. however i am using:
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
The Code Is:
return Scaffold(
body: LayoutBuilder(builder: (context, constraints) {
return SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Container(
height: constraints.maxHeight,
child: Stack(children: <Widget>[
Container(color: Colors.red,height: 300,),
Container(
margin: EdgeInsets.only(
top: screen.isPhone ? 150 : 240,
),
child: Column(
children: [
Card(
elevation: 5,
child: ListView.builder(
itemCount: 20,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) =>
ProductItemWidget(showDeleteIconButton: true),
),
),
Text("HEY"),
],
),
),
remove height: constraints.maxHeight,
Below is my code, I want to add some extra space of height 50, which comes at the end of list item. because when my second child of stack appears it nearly overlaps the last item of list view. I've tried wrapping ListView.builder with column and added a container at last but destroyed my whole structure. for this scenario I've to wrap the column into Single scrollable which pushed stack 2nd widget to be at the end of ListItem.(But I don't want Stack 2nd object to be scrollable).
As you can see I'm not able to click on HotDog.
body: Stack(
children: <Widget>[
ListView.builder(
itemCount: itemData.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context,int index){
return Text(data[index].name);
}
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.cyan
),
padding: EdgeInsets.all(10),
height: 60,
),
)
],
),
How about you add empty last item like below code?
ListView.builder(
itemCount: itemData.length + 1,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context,int index){
if (index == item.Data.length) {
return SizedBox(height: 50);
} else {
return Text(data[index].name);
}
}
),
ListViewBuilder should be wrap inside Expanded widget which will take fullscreen
and give container bottom width as per need.
Example:
var itemData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
Stack(
children: <Widget>[
Column(
children: <Widget>[
Expanded(
child: Container(
margin: EdgeInsets.only(bottom: 20),
child: ListView.builder(
itemCount: itemData.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 80,
child: Text("Text :" + index.toString()));
}),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.cyan),
padding: EdgeInsets.all(10),
height: 60,
),
),
)
],
),
],
),
Output:
This can be easily done by adding bottom padding in listview.builder
Expanded(
child: ListView.builder(
padding: EdgeInsets.only(bottom: 100), //Increase this as per your requirment
itemCount: 5,
itemBuilder: (cxt , idx) {
return YourWidget();
}
Since you're listview.builder is inside a stack, you simply use the Positioned widget for this. Simply wrap your listview with Positioned like below:
Positioned(
bottom:50, //adjust this since this is the padding inside the stack
child:Container(
width:MediaQuery.of(context).size.width //width of the whole phone
child: ListView.builder(
itemCount: itemData.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context,int index){
return Text(data[index].name);
}
),
),
),
To ensure your Container stays at the bottom wrap it with a positioned widget and set the bottom property to 0:
Positioned(
bottom:0, //adjust this since this is the padding inside the stack
child:Container(),
),
Here is a one minute clip showing how to use the Positioned widget: https://www.youtube.com/watch?v=EgtPleVwxBQ
There is no specific way to do it by default you have to do it manually with own logic
ListView.builder(
itemCount: itemData.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context,int index){
if(index == itemData.length - 1 )
return Padding(
padding: EdgeInsets.only(bottom : 50),
child : Text(data[index].name)
);
return Text(data[index].name);
}),
I have a SliverToBoxAdapter containing a ListView of FilterChips. I want to add a title at the beginning of ListView but I'm always getting a Horizontal viewport was given unbounded width error.
Here's my code:
SliverToBoxAdapter(
child: Container(
height: 70,
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: _expectedAnswers.length,
separatorBuilder: (context, index) {
return SizedBox(height: 7, width: 7);
},
itemBuilder: (context, index) {
return FilterChip(
label: Text('Hello');
// rest of FilterChip params here
);
},
),
),
);
This code as is works OK. But when I'm trying to add a title in front of the list, I'm getting the error above. Here's my attempt:
SliverToBoxAdapter(
child: Container(
height: 70,
child: Row(
children: <Widget>[
Text('Title'),
ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: _expectedAnswers.length,
separatorBuilder: (context, index) {
return SizedBox(height: 7, width: 7);
},
itemBuilder: (context, index) {
return FilterChip(
label: Text('Hello');
// rest of FilterChip params here
);
},
),
],
),
I have used clipToPadding in android to clip the padding while scrolling horizontally and vertically. Is there any specific attribute like clipToPadding in flutter? The behavior would look alike:
ListView.separated(
padding: EdgeInsets.all(16),
scrollDirection: Axis.horizontal,
separatorBuilder: (context, index) => SizedBox(
width: 8,
),
itemBuilder: (BuildContext context, int index) {
return Text(data[index].name);
},
itemCount: data.length,
)
I'm not a native android dev, but if I did understand right the "clipToPadding" option, you just want to remove padding from the ListView and add padding around it.
Container(
height: 100.0,
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: ListView.separated(
scrollDirection: Axis.horizontal,
separatorBuilder: (context, index) => SizedBox(
width: 8,
),
itemBuilder: (BuildContext context, int index) {
return AspectRatio(
aspectRatio: 1.0,
child: Container(
color: Colors.grey[300],
child: Center(child: Text(index.toString())),
),
);
},
itemCount: 20,
),
),
OR using Container (it's just to set max height for the listview) + separate Padding:
Container(
height: 100.0,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: ListView.separated(
scrollDirection: Axis.horizontal,
separatorBuilder: (context, index) => SizedBox(
width: 8,
),
itemBuilder: (BuildContext context, int index) {
return AspectRatio(
aspectRatio: 1.0,
child: Container(
color: Colors.grey[300],
child: Center(child: Text(index.toString())),
),
);
},
itemCount: 20,
),
),
),