How to take available space using container in Flutter - flutter

I was trying to make an app with SingleChildScrollView and ListView using below code
SingleChildScrollView(
child: Column(
children: [
maintile(),
Container(
padding: EdgeInsets.all(15.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topRight: Radius.circular(75.0),
),
),
child: ListView.builder(
shrinkWrap: true,
primary: false,
itemCount: items.length,
itemBuilder: (context, index) {
return listitem();
},
),
),
],
),
but the listview holding container does not take available space If I provide Expandable around it. is there any way to achieve Container take available space?

Use Expanded for Container parent like this :
Expanded(
child: Container(
child: Text("YOUR_WIDGET"),
),
)

Final Code:
final screenSize = MediaQuery.of(context).size;
return SafeArea(
child: Scaffold(
body: Container(
height: screenSize.height,
width: screenSize.width,
child: Column(
children: [
maintile(),
Expanded(
child: Container(
padding: EdgeInsets.all(15.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topRight: Radius.circular(75.0),
),
),
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: items.length,
itemBuilder: (context, index) {
return listitem();
},
),
),
),
],
),
)
),
);

Related

flutter ListView Separated

i tried to use listViewSeparated on a Widget along a row with scrolling but it doesn't show anything like its only a Scaffold (white page) i don't know what is the problem
Here is my code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../layout/cubit/cubit.dart';
import '../../layout/cubit/states.dart';
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return BlocConsumer<LifeStyleCubit, LifeStates>(
listener: (context, state) {},
builder: (context, state) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(8.0),
child: SingleChildScrollView(
child: Column(
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
ListView.separated(
shrinkWrap: true,
itemBuilder: (context,index) =>SpecialProgramWidget(),
separatorBuilder: (context,index) => SizedBox(width: 20,),
itemCount: 3
),
],
),
),
],
),
),
),
);
},
);
}
Widget SpecialProgramWidget() => Container(
width: 310,
height: 300,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: [
Stack(
alignment: Alignment.bottomRight,
children: [
Container(
height: 230,
width: 310,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10)),
image: DecorationImage(
image: NetworkImage(
'https://i.pinimg.com/564x/20/bd/68/20bd68b5a248bb191178bd9b98b53a76.jpg'),
fit: BoxFit.cover)),
),
Align(
alignment: Alignment.topLeft,
child: Container(
height: 230,
width: 290,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://www.pngplay.com/wp-content/uploads/6/Fitness-PNG-HD-Quality.png'),
fit: BoxFit.cover)),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Special Program',
style: TextStyle(fontSize: 21, color: Colors.white),
),
)
],
),
Container(
width: 310,
height: 70,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
),
border: Border.all(color: Colors.grey.shade400, width: 1),
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Align(
alignment: Alignment.topLeft,
child: Text(
'Super pump biceps workout',
style: TextStyle(
fontSize: 15,
),
)),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Align(
alignment: Alignment.topLeft,
child: Text(
'6 Weeks',
style: TextStyle(fontSize: 15, color: Colors.grey),
)),
),
],
),
)
],
),
);
}
i need my screen displayed like this
return Scaffold(
body: Column(
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
SpecialProgramWidget(),
SizedBox(width: 20,),
SpecialProgramWidget(),
SizedBox(width: 20,),
SpecialProgramWidget()
],
),
),
],
)
);
Which it displays the widget along a row... i wanted to do the same thing with ListViewSeparated but i only got White page with no data
i tried some solutions like wrapping Expanded widget on ListViewSeparated but still doesn't work
how can i solve this ?
The issue is on scrollDirection: Axis.horizontal,. Also you dont need to use ListView.separated( inside SingleChildScrolView, the parent is already handling the scroll event.
You can provide fixed with ListView.separated to bypass the issue,
Widget build(BuildContext context) {
// return
// BlocConsumer<LifeStyleCubit, LifeStates>(
// listener: (context, state) {},
// builder: (context, state) {
return Scaffold(
body: LayoutBuilder(
builder: (_, constraints) => Padding(
padding: const EdgeInsets.all(8.0),
child: SingleChildScrollView(
child: Column(
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
SizedBox(
width: constraints.maxWidth,
child: ListView.separated(
shrinkWrap: true,
itemBuilder: (context, index) =>
SpecialProgramWidget(),
separatorBuilder: (context, index) =>
SizedBox(width: 20),
itemCount: 3,
),
),
],
),
),
],
),
),
),
),
// );
// },
);
}
A better decision will be using CustomScrolView I think it will be better for the thing you are trying to get.

The images from list in another dart file won't be display on the output, what is the solution?

I want to show the images that are from list in another dart file but it won't display anything
instead it shows the loading icon, however I used (future, futurebuilder, expended and builder in listview.builder )
As shown in the code !!
Whatever I tried it showed an exception as followed a little piece of it:
(RenderFlex children have non-zero flex)
SingleChildScrollView(
child: FutureBuilder(
future: _getimages(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? Expanded(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 10),
),
Container(
height: 100,
width: 500,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
padding: const EdgeInsets.all(20),
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
List reslist = snapshot.data;
children:
[
Card(
child: Center(
child: Container(
child: ClipRRect(
borderRadius:
BorderRadius.circular(20),
child: Image.asset(
reslist[index].toString(),
fit: BoxFit.cover,
width: 500,
height: 500,
)),
),
),
elevation: 10,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(15),
),
),
];
return Center(
child: CircularProgressIndicator());
}),
),
],
),
)
: Center(child: CircularProgressIndicator());
}),
),
The output:
You should remove the children from the ListView.builder, and the Card should be returned instead of a CircularProgressIndicator. children is needed for ListView not its builder variant.
This is because you're returning a CircularProgressIndicator instead of Card just do the following changes to your code:
SingleChildScrollView(
child: FutureBuilder(
future: _getimages(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? Expanded(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 10),
),
Container(
height: 100,
width: 500,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
padding: const EdgeInsets.all(20),
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
List resList = snapshot.data;
return Card(
child: Center(
child: Container(
child: ClipRRect(
borderRadius:
BorderRadius.circular(20),
child: Image.asset(
resList[index].toString(),
fit: BoxFit.cover,
width: 500,
height: 500,
)),
),
),
elevation: 10,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(15),
),
);
}),
),
],
),
)
: Center(child: CircularProgressIndicator());
}),
)

Rounded ends on horizontal listview flutter

do you know if there is any way i could make my listview ends rounded?
Ive tried wraping the listview builder in a container with box decoration, borderadius and it did not work.
Any help is appreciated.
How it looks like:
https://i.stack.imgur.com/Jr4WJ.png
my code:
Padding(
padding: EdgeInsets.only(left: 5.0),
child: Container(
color: null,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: profiles[0].skills.length,
itemBuilder: (BuildContext context, int index) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15)),
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
setState(() {
_filterselectedIndex = index;
});
print(index);
} //setState(() => _filterselected = index)
,
child: Align(
alignment: Alignment.centerRight,
child: Container(
margin: EdgeInsets.all(10.0),
height: 32,
//width: 100,
decoration: BoxDecoration(
color: _filterselectedIndex == index
? Theme.of(context).accentColor
: Colors.white,
borderRadius:
BorderRadius.circular(15.0),
),
child: Padding(
padding: EdgeInsets.only(
left: 20,
right: 20,
),
child: Align(
alignment: Alignment.center,
child: Text(
profiles[0].skills[index],
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w600,
),
),
),
),
),
),
),
);
},
),
))
Yes, there are multiple ways. The easiest way i think would be using containers. Wrap your widget with a container widget. Then add decoration to it like the code below :
return ListView.builder(
itemBuilder: (context, position) {
return Container(
decoration: BoxDecoration(
color: Colors.black,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(25.0),
bottomRight: Radius.circular(25.0))),
child: Paste your existing code.
))
You can also do it using ClipRRect.
If I am correctly understanding your question you want to want to round the corner of yours listView, SO there are various method of doing that, One method is Wrapping the Listview in Container and then in decoration giving it borderRadous.
I have implemented the same functionality for you.
here is the code.
return Scaffold(
appBar: AppBar(
title: Text("App Bar"),
),
body: Container(
padding: EdgeInsets.all(26),
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.circular(
16) // <- incease the value for more rounded corner
),
child: ListView(
children: <Widget>[
Text("List Item 1"),
Divider(),
Text("List Item 1"),
Divider(),
Text("List Item 1"),
Divider(),
Text("List Item 1"),
Divider(),
],
),
),
);
I have a clone of app where I have implemented this type of listview with greater functionality like gestures and divider and other. (https://github.com/atul-chaudhary/country_dairy/blob/master/lib/user_func/user_menu.dart)
There are two ways of doing this,
First is using Container and second is ClipRRect
*Note: If you will use Container the widgets inside it will flow out if your BorderRadius will be a large number. But in ClipRRect this will not happen, it will stay inside.
See the code:
Using Container
Container(
height: 200.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(50.0))
),
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
color: Colors.blue,
width: 150.0,
),
);
},
itemCount: 10
),
),
Using ClipRRect
SizedBox(
height: 200.0,
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(50.0)),
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
color: Colors.blue,
width: 150.0,
),
);
},
itemCount: 10
),
),
)

Flutter Scroll entire screen including gridview

I made an application called food gallery which just shows some random foods. So first I wanted a main image at the top, so I used a container to display it at the top. Then I implemented a grid view under the container to show the gridview images of food. But the issue is whenever I scroll the page, only the gridview is getting scrolled and the container is like pinned and not scrolling. Following is the code.
body: SafeArea(
// Container
child: Container(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
height: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
image: DecorationImage(
image:AssetImage('assets/burger.jpeg'),
fit: BoxFit.cover
)
)
),
),
//GridView
Expanded(
child: GridView.builder(
itemCount: name.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (BuildContext context, int index){
return Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
image:DecorationImage(
image: AssetImage('assets/${img[index]}'),
fit: BoxFit.cover
)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Container(
width: double.infinity,
height: 50.0,
color: Colors.grey[800].withOpacity(0.5),
child:Center(child: Text('${name[index]}',style: TextStyle(color: Colors.white,fontSize: 20.0)),)
),
],
),
),
);
})
),
],
),
),
),
),
);
}
}
This is how it looks
As you can see the container is pinned at the top. I want the entire screen to scroll not only the gridview. I tried using SingleChildScrollView and it's not working.
Change your column with a ListView, remove the Expanded and add these to lines to your GridView :
physics: ScrollPhysics(), // to disable GridView's scrolling
shrinkWrap: true,
So your code would be like:
SafeArea(
child: Container(
child: ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
height: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
image: DecorationImage(
image:AssetImage('assets/burger.jpeg'),
fit: BoxFit.cover
)
)
),
),
//GridView
GridView.builder(
shrinkWrap: true,
physics: ScrollPhysics(),
itemCount: name.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (BuildContext context, int index){
return Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
image:DecorationImage(
image: AssetImage('assets/${img[index]}'),
fit: BoxFit.cover
)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Container(
width: double.infinity,
height: 50.0,
color: Colors.grey[800].withOpacity(0.5),
child:Center(child: Text('${name[index]}',style: TextStyle(color: Colors.white,fontSize: 20.0)),)
),
],
),
),
);
}),
],
),
),
);
You should look into CustomScrollView
A CustomScrollView lets you supply slivers directly to create various scrolling effects, such as lists, grids, and expanding headers.
Example
CustomScrollView(
slivers: <Widget>[
const SliverAppBar(
pinned: true,
expandedHeight: 250.0,
flexibleSpace: FlexibleSpaceBar(
title: Text('Demo'),
),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 4.0,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.teal[100 * (index % 9)],
child: Text('Grid Item $index'),
);
},
childCount: 20,
),
),
SliverFixedExtentList(
itemExtent: 50.0,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.lightBlue[100 * (index % 9)],
child: Text('List Item $index'),
);
},
),
),
],
)
this is your code
//GridView
Expanded(
child: GridView.builder(
itemCount: name.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (BuildContext context, int index){
***
return Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
decoration: BoxDecoration(
add this if before return ( i added *** )
if(index == 0){
return Container //your container Image goes Here
}else{
// your last return for other items
}
I hope this help your ...

Adding a container to a Sliver

I just started to learn about slivers and they don't seem to work with any other Flutter widgets except for the ones that start with "Sliver". I tried adding a Container so I can add BorderRadius to decorate the list. But I got this error:
A RenderSliverFillRemaining expected a child of type RenderBox but
received a child of type RenderSliverToBoxAdapter.
Here's my code so far:
...
SliverFillRemaining(
child: SliverToBoxAdapter(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(36),
topRight: Radius.circular(36),
),
),
child: SliverPadding(
padding: const EdgeInsets.all(16),
sliver: SliverFixedExtentList(
itemExtent: 50.0,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.lightBlue[100 * (index % 9)],
child: Text('List Item $index'),
);
},
),
),
),
),
),
),
...
I solved my issue by using a NestedScrollView instead of a CustomScrollView.
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (context, innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
floating: false,
pinned: true,
snap: false,
elevation: 0,
expandedHeight: 150.0,
brightness: DynamicTheme.of(context).brightness,
flexibleSpace: FlexibleSpaceBar(
title: Text(assignment.name),
),
),
];
},
body: Container(
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(36),
topRight: Radius.circular(36),
),
),
child: ListView.builder(
itemExtent: 50.0,
itemBuilder: (context, index) {
return Container(
alignment: Alignment.center,
color: Colors.lightBlue[100 * (index % 9)],
child: Text('List Item $index'),
);
},
),
),
),
);
[UPDATE]
Based on your use case I think, you don't even need SliverFillRemaining, if you want the list inside SliverFillRemaining to be infinite, just use SliverList with SliverChildBuilderDelegate
...
SliverFixedExtentList(
itemExtent: 50.0,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.lightBlue[100 * (index % 9)],
child: Text('List Item $index'),
);
},
),
),
...
previous
You already have your answer in the error, you SliverFillRemaining doesn't use sliver, it uses child which should be widget
...
SliverFillRemaining(
hasScrollBody: true,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(36),
topRight: Radius.circular(36),
),
),
child: Padding(
padding: const EdgeInsets.all(16),
child: ListView.builder(
itemCount: 20,
physics: NeverScrollableScrollPhysics(), //adding this line will disable the scrolling and listview and so the CustomScrollView should work as a single scroll view
itemBuilder: (_, __) => ListTile(
title: Text("Item"),
),
),
),
),
),
...