Related
As you can see, Actually I want to make the screen scrollable, In my Flutter project, on one screen I have used some rows, columns, and listview but when I scroll my screen this is not happening, while I have to take SingleChildScrollView but it didn't work. and I have tried replacing the column with Listview but it didn't work. I don't understand where is the problem, please give me a solution. and I have attached my code and share a screenshot of the app screen below.
it shows pixel error.
.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import 'package:movie_app/core/constants/constants.dart';
import 'package:movie_app/ui/views/movielist/movie_detail_view.dart';
class MovieListView extends StatefulWidget {
const MovieListView({Key? key}) : super(key: key);
#override
_MovieListViewState createState() => _MovieListViewState();
}
class _MovieListViewState extends State<MovieListView> {
int counter = 0;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Color(0xff070d2d),
body: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Container(
child: Column(
children: [
_buildHeaderSection(),
_buildSearchBar(),
SizedBox(height: 30),
buildCategoriesSection(),
SizedBox(height: 20),
buildListCategories(),
SizedBox(height: 30),
_buildPopularTitle(),
SizedBox(height: 30),
_buildPopularSection(),
],
),
),
),
),
],
),
),
);
}
Widget _buildHeaderSection() {
return Container(
padding: EdgeInsets.fromLTRB(30.0, 80.0, 30.0, 60.0),
// color: Colors.red,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
onTap: (){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MovieDetailView()),
);
},
child: Text(
"Hi, Edwards!",
style: TextStyle(
fontSize: 25,
//fontWeight: FontWeight.bold,
color: Colors.white),
),
),
Stack(
children: [
new IconButton(
icon: Icon(Icons.notifications),
onPressed: () {
setState(() {
//counter = 0;
});
}),
counter != 0
? new Positioned(
left: 20,
top: 20,
child: new Container(
padding: EdgeInsets.all(2),
decoration: new BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(6),
),
constraints: BoxConstraints(
minWidth: 14,
minHeight: 14,
),
child: Text(
'$counter',
style: TextStyle(
color: Colors.white,
fontSize: 8,
),
textAlign: TextAlign.center,
),
),
)
: new Container(),
ClipRRect(
borderRadius: BorderRadius.circular(50.0),
child: Image.network(
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ9CbZTM7W7VmNIGF36hIjpJcVoWEhbPGEGSw&usqp=CAU",
height: 50.0,
width: 50.0,
),
),
],
)
],
),
);
}
Widget _buildSearchBar() {
return Container(
height: 50,
margin: EdgeInsets.only(left: 30, right: 30),
child: TextField(
decoration: InputDecoration(
prefixIcon: Icon(
Icons.search,
color: Colors.white,
),
hintText: "search your movie",
hintStyle: TextStyle(color: Colors.white),
fillColor: Colors.white,
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
borderSide: BorderSide(
color: Colors.white,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
borderSide: BorderSide(
color: Colors.grey,
width: 2.0,
),
),
)),
);
}
Widget buildCategoriesSection() {
return Container(
padding: EdgeInsets.only(left: 20, right: 20),
child: Row(
children: [
Text(
"Categories",
style: TextStyle(
color: Colors.white,
fontSize: 15,
),
),
SizedBox(
width: 150,
),
Text(
"See more",
style: TextStyle(
color: Colors.grey,
fontSize: 15,
),
)
],
),
);
}
Widget buildListCategories() {
return Container(
height: 80,
padding: EdgeInsets.only(left: 20),
width: MediaQuery.of(context).size.width,
child: Container(
child: ListView.builder(
itemCount: categoryList.length,
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemBuilder: (context, position) {
return _buildCategoryItem(categoryList[position]);
},
),
),
);
}
Widget _buildCategoryItem(String category) {
return Container(
height: 80,
width: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.red.withOpacity(0.3),
),
margin: EdgeInsets.only(right: 16),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.adb, color: Colors.white,),
SizedBox(height: 8),
Text(
category,
style: TextStyle(color: Colors.white),
),
],
),
);
}
_buildPopularTitle() {
return Container(
padding: EdgeInsets.only(left: 20, right: 20),
child: Row(
children: [
Text(
"Popular",
style: TextStyle(
color: Colors.white,
fontSize: 15,
),
),
SizedBox(
width: 150,
),
Text(
"See more",
style: TextStyle(
color: Colors.grey,
fontSize: 15,
),
)
],
),
);
}
_buildPopularSection() {
return Container(
height: 200,
padding: EdgeInsets.only(left: 20),
width: MediaQuery.of(context).size.width,
child: Container(
child: ListView.builder(
itemCount: 6,
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemBuilder: (context, position) {
return _buildPopularItem();
},
),
),
);
}
_buildPopularItem() {
return Column(
children: [
Container(
height: 200,
width: 150,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red,
),
margin: EdgeInsets.only(right: 16),
child: Image.network(
'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/movie-poster-template-design-21a1c803fe4ff4b858de24f5c91ec57f_screen.jpg?ts=1574144362',
fit: BoxFit.cover,
),
),
SizedBox(height: 5,),
Container(
color: Colors.green,
child: Text("data",style: TextStyle(
color: Colors.red
),
),
),
],
);
}
}
As you have mentioned SingleChildScrollView should work, but your problem is that you don't have enough items to be scrolled according to your screenshot.
So please use enough items and try again.
And in your _buildPopularItem() widget, decrease the container width, that's why it says pixel overflow.
This overflow is made from _buildPopularTitle() while you set fixed height from _buildPopularSection having height: 200,
if you look closely, inside _buildPopularItem
There is a Container with height: 200, and it is taking full height, so for rest of children SizedBox h:5 and Container Text aren't having any spaces here, and creating overflow.
Solutions
increase the height of _buildPopularSection
reduce the container height inside _buildPopularItem
wrap with FittedBox(child: _buildPopularItem());
From the screenshot I can see that your container is smaller by 21 pixels in height. Please increase it.
_buildPopularSection() {
return Container(
height: 230,
padding: EdgeInsets.only(left: 20),
width: MediaQuery.of(context).size.width,
child: Container(
child: ListView.builder(
itemCount: 6,
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemBuilder: (context, position) {
return _buildPopularItem();
},
),
),
);
}
_buildPopularItem() {
return Column(
children: [
Container(
height: 225,
width: 150,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.red,
),
margin: EdgeInsets.only(right: 16),
child: Image.network(
'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/movie-poster-template-design-21a1c803fe4ff4b858de24f5c91ec57f_screen.jpg?ts=1574144362',
fit: BoxFit.cover,
),
),
SizedBox(height: 5,),
Container(
color: Colors.green,
child: Text("data",style: TextStyle(
color: Colors.red
),
),
),
],
);
}
Replace the above code and it should work...
I am running into issues pushing down the listview out of view of the draggablescrollablesheet (sheet) while still being able to scroll the sheet. So in simpler words I do not want the blue container to show up when the sheet is at the bottom.
I have tried to edit the height of the listview container and that makes it go offscreen therefore unscrollable.
I have also tried wrapping the sheet in a singlechildscrollview with no luck. I am trying to avoid using a button at all possible costs!
import 'package:flutter/material.dart';
import 'package:photosgroup2/chat/message_model.dart';
import 'package:photosgroup2/chat/user_model.dart';
class FeedTest extends StatefulWidget {
FeedTest({Key key}) : super(key: key);
#override
_FeedTest createState() => _FeedTest();
}
class _FeedTest extends State<FeedTest> {
_buildMessage(
Message message,
User user,
) {
//Reply reply){
String time= message.time;
return Container(
// color: Colors.yellow,
child: Padding(
padding: EdgeInsets.only(left: 0), //5
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(left: 5 ,top: 3.5), //10
child: new CircleAvatar(
radius: (17.5),
backgroundImage: AssetImage(
user.profilePic,
),
),
),
SizedBox(
width: 5,
),
Container(
//width: MediaQuery.of(context).size.width,
// width: 300,
child: Material(
color:Color(0x00000000) , //TRANSPARENT
//color: const Color(0xf2ffffff),
///Color(0xe6ffffff) // ! REVISIT Change color of boxes???
/*borderRadius: BorderRadius.only(
topRight: Radius.circular(16.0),
bottomRight: Radius.circular(16.0),
bottomLeft: Radius.circular(16.0),
),*/
child: Padding(
padding: EdgeInsets.only(
left: 10.0), //Revisit
child: Column(
//mainAxisSize: MainAxisSize.min,
mainAxisSize: MainAxisSize.min,
//crossAxis
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 5,
),
Text(
user.name,
style: TextStyle(
fontFamily: 'Lato-Bold',
fontSize: 13 ,
color: const Color(0xd9343f4b),
),
textAlign: TextAlign.left,
),
SizedBox(width: 8),
Padding(
padding: const EdgeInsets.only(left:8.0),
child: Text(
'$time hours ago',
style: TextStyle(
fontFamily: 'Lato',
fontSize: 12 ,
color: const Color(0xff5a6978),
),
textAlign: TextAlign.left,
),
),
SizedBox(
height: 5,
),
//SizedBox(height: 10,),//if(message.imageUrl!='') {
//hasReplies(message, user, reply)
//},
//}
],
),
),
),
),
],
),
SizedBox(height:5),
Container(
//color:Colors.blue,
//: EdgeInsets.only(right:10
//right: 10 * SizeConfig.widthRatio,
//),
child: Container(
//color: Colors.green,
margin: EdgeInsets.only(left:5,right:15),
child: Text(
message.text,
style: TextStyle(
fontFamily: 'Lato',
fontSize: 13 ,
color: const Color(0xff5a6978),
height: 1.5384615384615385
),
textAlign: TextAlign.left,
),
),
),
SizedBox(//color:Colors.amber,
height:15),
Transform.translate(
offset: Offset(-6,0),
child: Container(
width: 350.0,
height: 0.5,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(1.0),
color: const Color(0x40343f4b),
),
),
),
SizedBox(//color:Colors.amber,
height:5),
],
),
),
);
}
#override
Widget build(BuildContext context) {
// visibility of reply button in top right corner
return Scaffold(
backgroundColor: const Color(0xfffafafa),
body: SafeArea(
bottom: false,
top: false,
child: //Column(
//mainAxisAlignment: MainAxisAlignment.spaceAround,
//children: <Widget>[
Stack(
children: <Widget>[
DraggableScrollableSheet(
initialChildSize: 0.068,
minChildSize: 0.068,
maxChildSize: 0.71,
builder: (context, scrollController) {
return Container(
//padding: EdgeInsets.symmetric(horizontal: 20),
child: Stack(
children: [
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(32),
topRight: Radius.circular(32),
),
child: Container(
width: 375, //screen width
height: 812 * 0.71, //screen height *
color: Color(0xffdfdfdf),
),
),
),
Stack(
children: [
Padding(
padding: const EdgeInsets.only(left: 10, top: 20.0),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(27.5),
topRight: Radius.circular(27.5),
),
child: Container(
//margin: EdgeInsets.only(),
width:340,
//height: 515,
color: Colors.yellow,
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(27.5),
topRight: Radius.circular(27.5),),
child: Container(
// padding: EdgeInsets.only(top:40),
color: Colors.blue,
child: ListView.builder(
//reverse: true,
controller: scrollController,
itemCount: comments.length,
itemBuilder: (BuildContext context, int index) {
final User messenger = comments[index].sender;
final Message message = comments[index];
//final Reply reply = replies[index];
return Column(children: <Widget>[
_buildMessage(
message,
messenger,
), //reply),
SizedBox(
height: 8,
) // !COME BACK TO SPACE BETWEEN
]);
},
),
),
),
),),
),
],
),
Stack(
children: <Widget>[
//67
Padding(
padding: EdgeInsets.only(left: 141, top: 6),
child: SizedBox(
width: 93.0,
height: 29.0,
child: Stack(
children: <Widget>[
SizedBox(
width: 93.0,
height: 29.0,
child: Stack(
children: <Widget>[
// Adobe XD layer: 'Rectangle' (shape)
Container(
width: 93,
height: 29.0,
child: Padding(
padding: EdgeInsets.only(
left: 1, top: 6),
child: Text(
'Place Holder',
style: TextStyle(
fontFamily: 'Lato',
fontSize: 12,
color: const Color(0xffffffff),
),
textAlign: TextAlign.center,
),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(27.5),
color: const Color(0xf2343f4b),
),
),
],
),
),
],
),
),
),
],
),
],
),
);
},
),
],
),
// ],
//),
),
);
}
}
I am struggling with this, How Can I achieve this design? My code included stack widget with container background image but it's not showing properly.
I tried and it's showing like bellow image,
I want to design exactly like first image, I am stucking on positioning of small camera icon, background image, buy now banner etc, here's my code-
Stack(
children: [
Container(
decoration: new BoxDecoration(
// color: Colors.transparent,
image: new DecorationImage(
fit: BoxFit.fill,
image: new AssetImage(
'images/icons/egle2.png',
),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Column(
children: [
Stack(
alignment: Alignment.topCenter,
children: [
Container(
height: 100,
width: 100,
),
Positioned(
// right: 1.0,
child: Material(
elevation: 8.0,
color: Colors.blue,
shape: CircleBorder(),
child: CircleAvatar(
maxRadius: 50,
minRadius: 40,
backgroundColor: Colors.transparent,
backgroundImage: AssetImage(
'images/icons/jully.png'),
),
),
),
// SizedBox(
// width: 20,
// ),
Positioned(
right: 0.0,
top: 0.0,
child: Align(
alignment: Alignment.topRight,
child: Image.asset(
'images/icons/camera.png',
// height: ,
// width: 25,
),
),
),
],
),
SizedBox(
height: 5,
),
Text(
'Jully',
style: TextStyle(
color: Colors.white, fontSize: 18),
),
SizedBox(
height: 5,
),
GestureDetector(
onTap: null,
child: Container(
padding: EdgeInsets.all(5),
height: 25,
// width: 30,
decoration: BoxDecoration(
color: UniversalVariables.yellowColor,
borderRadius: BorderRadius.circular(4),
),
child: Row(
children: [
Icon(
Icons.card_giftcard,
size: 15,
),
SizedBox(
width: 2,
),
Text(
'ID: 123875',
style: TextStyle(fontSize: 12),
),
],
),
),
),
SizedBox(
height: 200,
),
],
),
Column(
children: [
Stack(
alignment: Alignment.topCenter,
children: [
Container(
height: 100,
width: 100,
),
Positioned(
right: 1.0,
child: Material(
elevation: 8.0,
color: Colors.blue,
shape: CircleBorder(),
child: CircleAvatar(
maxRadius: 50,
minRadius: 40,
backgroundColor: Colors.transparent,
backgroundImage:
AssetImage('images/icons/king.png'),
),
),
),
SizedBox(
width: 20,
),
Positioned(
right: 0.0,
top: 0.0,
child: Align(
alignment: Alignment.topRight,
child: Image.asset(
'images/icons/camera.png',
// height: ,
// width: 25,
),
),
),
],
),
SizedBox(
height: 5,
),
Text(
'King_20',
style: TextStyle(
color: Colors.white, fontSize: 18),
),
SizedBox(
height: 5,
),
GestureDetector(
onTap: null,
child: Container(
padding: EdgeInsets.all(5),
height: 25,
// width: 30,
decoration: BoxDecoration(
color: UniversalVariables.yellowColor,
borderRadius: BorderRadius.circular(4),
),
child: Row(
children: [
Icon(
Icons.card_giftcard,
size: 15,
),
SizedBox(
width: 2,
),
Text(
'ID: 123875',
style: TextStyle(fontSize: 12),
),
],
),
),
),
],
),
Column(
children: [
Stack(
alignment: Alignment.topCenter,
children: [
Container(
height: 100,
width: 100,
),
Positioned(
right: 1.0,
child: Material(
elevation: 8.0,
color: Colors.blue,
shape: CircleBorder(),
child: CircleAvatar(
maxRadius: 50,
minRadius: 40,
backgroundColor: Colors.transparent,
backgroundImage:
AssetImage('images/icons/hulk.png'),
),
),
),
SizedBox(
width: 20,
),
Positioned(
// top: 5.0,
right: 0.0,
child: Container(
child: Image.asset(
'images/icons/camera.png',
// height: ,
// width: 25,
),
),
),
],
),
SizedBox(
height: 5,
),
Text(
'Hulk',
style: TextStyle(
color: Colors.white, fontSize: 18),
),
SizedBox(
height: 5,
),
GestureDetector(
onTap: null,
child: Container(
padding: EdgeInsets.all(5),
height: 25,
// width: 30,
decoration: BoxDecoration(
color: UniversalVariables.yellowColor,
borderRadius: BorderRadius.circular(4),
),
child: Row(
children: [
Icon(
Icons.card_giftcard,
size: 15,
),
SizedBox(
width: 2,
),
Text(
'ID: 123875',
style: TextStyle(fontSize: 12),
),
],
),
),
),
SizedBox(
height: 200,
),
// Stack(
// alignment: Alignment.topCenter,
// children: [
// Container(
// height: 100,
// width: 100,
// ),
// Positioned(
// right: 1.0,
// child: Material(
// elevation: 8.0,
// color: Colors.blue,
// shape: CircleBorder(),
// child: CircleAvatar(
// maxRadius: 50,
// minRadius: 40,
// backgroundColor: Colors.transparent,
// backgroundImage: AssetImage(
// 'images/icons/happyman.png'),
// ),
// ),
// ),
// SizedBox(
// width: 20,
// ),
// Positioned(
//// top: 5.0,
// right: 0.0,
// child: Container(
// child: Image.asset(
// 'images/icons/camera.png',
//// height: ,
//// width: 25,
// ),
// ),
// ),
// ],
// ),
// SizedBox(
// height: 5,
// ),
// Text(
// 'Happy Man',
// style: TextStyle(
// color: Colors.white, fontSize: 18),
// ),
// SizedBox(
// height: 5,
// ),
// GestureDetector(
// onTap: null,
// child: Container(
// padding: EdgeInsets.all(5),
// height: 25,
//// width: 30,
// decoration: BoxDecoration(
// color: UniversalVariables.yellowColor,
// borderRadius: BorderRadius.circular(4),
// ),
// child: Row(
// children: [
// Icon(
// Icons.card_giftcard,
// size: 15,
// ),
// SizedBox(
// width: 2,
// ),
// Text(
// 'ID: 123875',
// style: TextStyle(fontSize: 12),
// ),
// ],
// ),
// ),
// ),
],
),
],
),
),
Positioned.fill(
top: 280,
child: Container(
color: Colors.yellow,
height: 100,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(left: 20),
child: Container(
child: Row(
children: [
Image.asset('images/icons/badge4.png',),
SizedBox(width: 10,),
Text(
"X 70 = \$10",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold),
),
],
),
),
),
Padding(
padding: const EdgeInsets.only(right: 20),
child: GestureDetector(
onTap: null,
child: Container(
padding: EdgeInsets.all(8),
height: 35,
// width: 30,
decoration: BoxDecoration(
color: UniversalVariables.blackColor,
borderRadius: BorderRadius.circular(4),
),
child: Row(
children: [
Text(
'Buy Now',
textAlign: TextAlign.center,
style:
TextStyle(color: Colors.white),
),
],
),
),
),
),
],
),
),
),
],
),
As usual, there might be better examples on how to achieve this result.
Here's a fast attempt to recreate it. It needs some fine tuning to fit any screen size, using AutoSizeText and rewriting PersonDrawer to be responsive too.
But I hope that it will help you to move in the right direction.
class MySuperCoolStackWidget extends StatelessWidget {
final double baseWidth = 520.0;
final double baseHeight = 345.0;
double fromWidth(double size, BoxConstraints constraints) {
return size / baseWidth * constraints.maxWidth;
}
double fromHeight(double size, BoxConstraints constraints) {
return size / baseHeight * constraints.maxHeight;
}
#override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: baseWidth / baseHeight,
child: LayoutBuilder(
builder: (context, constraints) {
return Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.black,
),
),
AspectRatio(
aspectRatio: 520.0 / 260.0,
child: Container(
padding: EdgeInsets.fromLTRB(
fromWidth(20.0, constraints),
fromHeight(40.0, constraints),
fromWidth(20.0, constraints),
fromHeight(20.0, constraints),
),
child: LayoutBuilder(
builder: (_, innerConstraints){
return Row(
children: <Widget>[
Expanded(
child: PersonDrawer(),
),
SizedBox(
width: fromWidth(20.0, constraints),
),
Expanded(
child: Transform.translate(
offset: Offset(0.0, innerConstraints.maxHeight / 2.0),
child: PersonDrawer(),
),
),
SizedBox(
width: fromWidth(20.0, constraints),
),
Expanded(
child: PersonDrawer(),
),
],
);
},
),
),
),
Positioned(
left: 0,
right: 0,
bottom: fromHeight(20.0, constraints),
child: AspectRatio(
aspectRatio: 520.0 / 65.0,
child: Container(
padding: EdgeInsets.symmetric(
vertical: fromHeight(16.0, constraints),
horizontal: fromWidth(32.0, constraints),
),
color: Colors.orange[400],
child: Row(
children: <Widget>[
Expanded(
child: Row(
children: <Widget>[
Icon(Icons.local_florist),
Text('x 70 = \$10'),
],
),
),
RaisedButton(
color: Colors.black,
textColor: Colors.white,
onPressed: () {},
child: Text('Buy now'),
),
],
),
),
),
),
],
);
},
),
);
}
}
class PersonDrawer extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white10,
border: Border.all(color: Colors.white12),
borderRadius: BorderRadius.circular(10.0),
),
child: Column(
children: <Widget>[
Expanded(
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
padding: EdgeInsets.all(10.0),
child: AspectRatio(
aspectRatio: 1.0,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
),
),
),
),
Positioned(
top: 5.0,
right: 5.0,
child: Icon(
Icons.camera,
color: Colors.white,
),
),
],
),
),
SizedBox(height: 5.0),
Container(
padding: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
Text(
'King_20',
style: TextStyle(
color: Colors.white,
),
),
SizedBox(height: 5.0),
Container(
padding: EdgeInsets.all(2.0),
decoration: BoxDecoration(
color: Colors.orange[400],
borderRadius: BorderRadius.circular(5.0),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(Icons.perm_identity, size: 10.0),
Text(
'ID: 1234567',
style: TextStyle(
fontSize: 10.0,
),
),
],
),
),
],
),
)
],
),
);
}
}
I have the following view.
I would like the "confirm" button to always appear at the bottom of the slide up panel no matter what device is being used. If I position at the bottom correctly using padding or empty containers it is cut off on smaller screen size. Or if I position correctly on a smaller screen I am now running into issues with white space at the bottom. I am using the safe area widget which I thought ensured all widgets stay within the SafeArea?
Here is my code so far:
class ChooseAppointmentView extends StatefulWidget {
#override
_ChooseAppointmentViewState createState() => _ChooseAppointmentViewState();
}
class _ChooseAppointmentViewState extends State<ChooseAppointmentView> {
final List<Appointment> appointmentList = [
Appointment("Monday", DateTime.now(), DateTime.now(), "AM"),
Appointment("Tuesday", DateTime.now(), DateTime.now(), "AM"),
Appointment("Wednesday", DateTime.now(), DateTime.now(), "PM"),
Appointment("Thursday", DateTime.now(), DateTime.now(), "AM"),
Appointment("Friday", DateTime.now(), DateTime.now(), "PM"),
];
DateTime _dateSelected = DateTime.now();
DateTime _initialiseDate = DateTime.now();
#override
Widget build(BuildContext context) {
BorderRadiusGeometry radius = BorderRadius.only(
topLeft: Radius.circular(24.0),
topRight: Radius.circular(24.0),
);
return BaseView<ConfirmDetailsViewModel>(
builder: (context, model, child) => Scaffold(
backgroundColor: AppColours.primaryColour,
body: SafeArea(
child: WillPopScope(
onWillPop: () async {
return false;
},
child: SlidingUpPanel(
maxHeight: MediaQuery.of(context).size.height * .80,
minHeight: 75.0,
parallaxEnabled: true,
parallaxOffset: .5,
panel: Stack(
children: <Widget>[
Center(
child: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.02),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 30,
height: 5,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius:
BorderRadius.all(Radius.circular(12.0))),
),
],
),
Container(
height: MediaQuery.of(context).size.height * 0.02),
Container(
child: Text(
"Select a date in here.",
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 24.0,
),
),
),
Container(
height: MediaQuery.of(context).size.height * 0.05),
Container(
height: 200,
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.date,
minimumDate: _initialiseDate,
maximumDate: _initialiseDate.add(Duration(days: 7)),
initialDateTime: _initialiseDate,
onDateTimeChanged: (dateSelected) {
setState(() {
_dateSelected = dateSelected;
});
},
),
),
Container(
height: MediaQuery.of(context).size.height * 0.05),
Container(
height: 50.0,
width: MediaQuery.of(context).size.width - 50,
child: RaisedButton(
onPressed: () async {
//await model.submit();
Navigator.push(
context,
SizeRoute(
page: ChooseAppointmentView(),
),
);
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
),
child: Text('Confirm'),
color: AppColours.primaryLightColour,
textColor: Colors.white,
padding: EdgeInsets.fromLTRB(9, 9, 9, 9),
),
),
],
),
),
],
),
collapsed: Center(
child: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.02),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 30,
height: 5,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius:
BorderRadius.all(Radius.circular(12.0))),
),
],
),
Container(
height: MediaQuery.of(context).size.height * 0.02),
Container(
decoration: BoxDecoration(
color: Colors.white, borderRadius: radius),
child: Center(
child: Text(
"Select a different date",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.normal,
fontSize: 20.0,
),
),
),
),
],
),
),
body: Container(
decoration: BoxDecoration(color: Colors.white),
child: ListView.builder(
padding: EdgeInsets.only(bottom: 100.0),
itemCount: appointmentList.length,
itemBuilder: (BuildContext context, int index) =>
buildAppointmentCards(context, index),
),
),
borderRadius: radius,
),
),
),
),
);
}
Widget buildAppointmentCards(BuildContext context, int index) {
final appointment = appointmentList[index];
return Padding(
padding: const EdgeInsets.all(10.0),
child: Material(
color: Colors.white.withOpacity(0.0),
child: InkWell(
splashColor: Colors.red,
onTap: () {
print('card tapped');
},
child: new Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
gradient: LinearGradient(
colors: [
AppColours.primaryColour,
AppColours.primaryLightColour,
AppColours.primaryLighterColour,
//add more colors for gradient
],
begin: Alignment.topLeft, //begin of the gradient color
end: Alignment.bottomRight, //end of the gradient color
stops: [0, 0.2, 0.5] //stops for individual color
//set the stops number equal to numbers of color
),
borderRadius: BorderRadius.circular(10),
),
padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
child: Container(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 4.0, bottom: 4.0),
child: Row(
children: <Widget>[
Text(
appointment.day,
style:
TextStyle(fontSize: 30.0, color: Colors.white),
),
Spacer(),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 4.0, bottom: 80.0),
child: Row(
children: <Widget>[
Text(
"${DateFormat('hh:mm').format(appointment.date).toString()} - ${DateFormat('hh:mm').format(appointment.date).toString()}",
style:
TextStyle(fontSize: 20.0, color: Colors.white),
),
Spacer(),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0, bottom: 8.0),
child: Row(
children: <Widget>[
Text(
DateFormat(
'dd/MM/yyyy',
).format(appointment.date).toString(),
style:
TextStyle(fontSize: 20.0, color: Colors.white),
),
Spacer(),
Text(
appointment.ampm,
style:
TextStyle(fontSize: 20.0, color: Colors.white),
),
],
),
)
],
),
),
),
),
),
),
);
}
}
[enter link description here][2]
I think you can use the Align widget for positioning your widget in Stack. For more information can see in this link in this link you will see examples including explanation in the video.
I am using a white container with height
height: MediaQuery.of(context).size.height
And I am adding several red containers in it. When the number of these inside containers is less, the scrolling works perfectly like this
But as I increase the number of containers inside the big container, scrolling kind of overflows the container, like this
One solution I found out was that if I increase the height of white container, i.e:-
height: MediaQuery.of(context).size.height*7
But it makes the app look ugly and would eventually fail when the number of red containers is further increased. How can I fix this issue?
Code for the Program:-
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: Test(),
));
}
class Test extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(
child: Scaffold(
body: Container(
color: Colors.black,
child: ListView(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 15.0, left: 10.0),
),
SizedBox(
height: 25.0,
),
Padding(
padding: EdgeInsets.only(left: 20.0),
child: Row(
children: <Widget>[
Text(
'TEST',
style: TextStyle(
fontFamily: 'Montserrat',
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 25.0),
),
SizedBox(
width: 10.0,
),
],
),
),
SizedBox(height: 60.0,),
Container(
margin: EdgeInsets.only(top:180.0,),
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
color: Color(0xFFEEEEEE),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(75.0),
topRight: Radius.circular(75.0),
),
),
child: ListView(
primary: false,
padding: EdgeInsets.only(
left: 15.0,
right: 15.0,
top: 20.0,
),
children: <Widget>[
Padding(
padding: const EdgeInsets.only(
top: 30.0,
),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Center(
child: Text(
'TEST',
style: TextStyle(
color: Colors.black,
fontSize: 30.0,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
SizedBox(height: 20.0,),
Column(
children: <Widget>[
Container(
height: 150,
color: Colors.red,
),
SizedBox(height: 20,),
Container(
height: 150,
color: Colors.red,
),
SizedBox(height: 20,),
Container(
height: 150,
color: Colors.red,
),
SizedBox(height: 20,),
Container(
height: 150,
color: Colors.red,
),
SizedBox(height: 20,),
Container(
height: 150,
color: Colors.red,
),
SizedBox(height: 20,),
Container(
height: 150,
color: Colors.red,
),
SizedBox(height: 20,),
Container(
height: 150,
color: Colors.red,
),
SizedBox(height: 20,),
],
)
],
),
),
],
),
),
],
),
),
),
),
);
}
}
Okay so after some suggestions from comments I myself found the solution.
Instead of using listview inside the white container, I removed it and wrapped the white container with SingleChildScrollView and also wrapped it with Flexible
Now the container automatically adjusts according to the amount of containers in it.
Fixed code:-
import 'package:flutter/material.dart';
class Test extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(
child: Scaffold(
body: Container(
color: Colors.black,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 15.0, left: 10.0),
),
SizedBox(
height: 25.0,
),
Padding(
padding: EdgeInsets.only(left: 20.0),
child: Row(
children: <Widget>[
Text(
'TEST',
style: TextStyle(
fontFamily: 'Montserrat',
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 25.0),
),
SizedBox(
width: 10.0,
),
],
),
),
SizedBox(
height: 60.0,
),
//User INFO
SingleChildScrollView(
child: Flexible(
child: Container(
margin: EdgeInsets.only(
top: 180.0,
),
decoration: BoxDecoration(
color: Color(0xFFEEEEEE),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(75.0),
topRight: Radius.circular(75.0),
),
),
child: Padding(
padding: EdgeInsets.only(
left: 15.0,
right: 15.0,
top: 20.0,
),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(
top: 30.0,
),
child: Column(
children: <Widget>[
//greeting text
Row(
children: <Widget>[
Expanded(
child: Center(
child: Text(
'TEST',
style: TextStyle(
color: Colors.black,
fontSize: 30.0,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
SizedBox(
height: 20.0,
),
//app work
Column(
children: <Widget>[
Container(
height: 150,
color: Colors.red,
),
SizedBox(
height: 20,
),
Container(
height: 150,
color: Colors.red,
),
SizedBox(
height: 20,
),
Container(
height: 150,
color: Colors.red,
),
SizedBox(
height: 20,
),
Container(
height: 150,
color: Colors.red,
),
SizedBox(
height: 20,
),
Container(
height: 150,
color: Colors.red,
),
SizedBox(
height: 20,
),
Container(
height: 150,
color: Colors.red,
),
SizedBox(
height: 20,
),
Container(
height: 150,
color: Colors.red,
),
SizedBox(
height: 20,
),
],
)
//add button
],
),
),
],
),
),
),
),
),
],
),
),
),
),
),
);
}
}
To achieve your desired layout try playing with padding value of this container
Container(padding: EdgeInsets.only(top: 35.0, ),
margin: EdgeInsets.only(top:180.0,),
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
color: Color(0xFFEEEEEE),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(75.0),
topRight: Radius.circular(75.0),
),
),
in my case i used padding: EdgeInsets.only(top: 35.0, ),
result
First, you need to get the correct screen height by reducing the extra top padding and appBar size (if that page contains appBar)
To do that simply add
appBar: PreferredSize(
preferredSize: Size.fromHeight(50),
child: AppBar(
automaticallyImplyLeading: false,
elevation: 0,
title: Text(
"Hello"
),
backgroundColor: const Color(0xFF005898),
)),
Then add this to height
double screenHeight = MediaQuery.of(context).size.height -
50 -
MediaQuery.of(context).padding.top; // Top Screen Height - appbarHeight - Top Padding(That top status bar on every phone)
Then Everything is as same but, Before SingleChildScrollView add a sizedBox then provide screenHeight and width as per requirement then in the child add scrollView and the rest of the code