Trouble Building a Scroll-able Page with a bottom-navigation-Bar - flutter

When I am adding a bottomNavigationBar to my Page, the body of my Page will disappear. I believe the porblem to be sourced with my use of SingleChildScrollView from other posts that I have read
It does not appear to matter where I call in the bottom navigation Bar the page stops working
-homeScreen.dart
import 'package:flutter/material.dart';
import 'package:second_try/Widgets/headerHome.dart';
import 'package:second_try/Widgets/menuHome.dart';
import 'package:second_try/Widgets/businessesList.dart';
class homeScreen extends StatefulWidget {
homeScreen({Key key, this.title}) : super(key: key);
final String title;
#override
_homeScreen createState() => _homeScreen();
}
class _homeScreen extends State<homeScreen> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(body: bodyHomePage()),
);
}
}
class bodyHomePage extends StatelessWidget {
const bodyHomePage({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SingleChildScrollView(
child: Column(children: <Widget>[
headerHome(),
homeMenu(),
businessesList(),
businessesList(),
]),
),
// bottomNavigationBar: bottomNavigation(),
),
);
}
}
-------------------------------------------------------------------------------------
headerHome
import 'package:flutter/material.dart';
class headerHome extends StatelessWidget {
const headerHome({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(bottom: 10.0),
child: Container(
height: 140,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Stack(
alignment: Alignment.topCenter,
children: <Widget>[
Container(
height: 140,
color: Colors.white,
),
Container(
height: 120,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.deepPurple,
Colors.deepPurpleAccent,
],
),
boxShadow: [
BoxShadow(
color: Colors.black,
blurRadius: 10,
),
]),
),
Positioned(
top: 98,
child: Container(
width: 340,
height: 40,
decoration: BoxDecoration(
boxShadow: [
new BoxShadow(
color: Colors.blueGrey[900],
offset: new Offset(0.0, 8.0),
blurRadius: 20.0,
)
],
borderRadius: BorderRadius.all(Radius.circular(20)),
color: Colors.white,
),
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Padding(
padding:
const EdgeInsets.only(top: 8, left: 10),
child: TextFormField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: "What are you looking for?",
hintStyle:
TextStyle(color: Colors.grey[700]),
),
),
),
),
Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Align(
alignment: Alignment.centerRight,
child: Icon(Icons.search,
color: Colors.deepPurple)),
),
),
])),
),
Container(
height: 100,
padding: EdgeInsets.only(top: 25),
child: Row(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 30),
height: 35,
/* child: Image(
image: AssetImage(
'lib/assets/white-boardwalk-icon.png',
),
),*/
),
],
),
),
Container(
height: 100,
padding: EdgeInsets.only(top: 25),
child: Row(
children: <Widget>[
Expanded(
child: Center(
child: Container(
child: Text(
'Boardwalk',
style:
TextStyle(fontSize: 30, color: Colors.white),
),
),
),
),
],
),
),
],
),
],
),
),
);
}
}
-----------------------------------------------------------------------------------------------
businessList.dart
import 'package:flutter/material.dart';
class businessesList extends StatelessWidget {
const businessesList({Key key}) : super(key: key);
Padding businessCard(String category, IconData categoryIcon) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Container(
margin: EdgeInsets.only(left: 21),
width: 200,
child: InkWell(
child: Column(
children: <Widget>[
Center(
child: Container(
height: 140,
width: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(14)),
gradient: LinearGradient(
colors: [Colors.deepPurple, Colors.deepPurpleAccent],
),
),
child: Icon(
categoryIcon,
size: 40.0,
color: Colors.white,
),
),
),
Padding(
padding: const EdgeInsets.only(top: 12),
child: Align(
alignment: Alignment.topLeft,
child: Text(
category,
style: TextStyle(
fontSize: 22,
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 6),
child: Row(
children: <Widget>[
Container(
alignment: Alignment.topLeft,
child: Icon(Icons.star, size: 16,)),
Container(
alignment: Alignment.topLeft,
child: Icon(Icons.star, size: 16,)),
Container(
alignment: Alignment.topLeft,
child: Icon(Icons.star, size: 16,)),
Container(
alignment: Alignment.topLeft,
child: Icon(Icons.star, size: 16,)),
Container(
alignment: Alignment.topLeft,
child: Icon(Icons.star, size: 16,)),
Padding(
padding: const EdgeInsets.only(left:6.0),
child: Text(
'(356)',
style: TextStyle(
fontSize: 14,
),
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 6),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'Sed ut perspiciatis unde omnis iste natus error sit',
style: TextStyle(
fontSize: 16,
),
),
),
),
],
),
),
));
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 6, bottom: 12.0),
child: Container(
height: 40,
child: Row(
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 35),
alignment: Alignment.centerLeft,
child: Text(
'List Header',
style: TextStyle(fontSize: 24),
)),
Expanded(
child: SizedBox(),
),
Container(
margin: EdgeInsets.only(right: 35),
alignment: Alignment.centerRight,
child: Text(
'View All',
style: TextStyle(fontSize: 16),
))
],
),
),
),
Container(
height: 260,
width: 400,
child:
ListView(scrollDirection: Axis.horizontal, children: <Widget>[
businessCard('Home', Icons.home),
businessCard('Eat', Icons.restaurant_menu),
businessCard('Shop', Icons.store),
businessCard('Travel', Icons.airplanemode_active),
businessCard('Play', Icons.local_activity),
businessCard('Service', Icons.business),
]),
),
],
),
);
}
--------------------------------------------------------------------------------
bottomNavigation.dart
import 'package:flutter/material.dart';
class bottomNavigation extends StatelessWidget {
const bottomNavigation ({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: 1,
items: [
BottomNavigationBarItem(icon: Icon(Icons.arrow_drop_up,), title: Text("GLO",
style: TextStyle(color: Colors.black),),),
BottomNavigationBarItem(icon: Icon(Icons.arrow_drop_up), title:
Text("MTN"),),
BottomNavigationBarItem(icon: Icon(Icons.arrow_drop_up), title:
Text("Airtel"),),
BottomNavigationBarItem(icon: Icon(Icons.arrow_drop_up), title:
Text("Airtel"),),
],
),
),
);
}
}
I am expecting both the Pages Screen and the navigation bar to be view-able but the two are not working together at the moment
I am not experiencing any error messages

_homeScreen, bodyHomePage and bottomNavigation build methods return MaterialApp - you should need only one MaterialApp, in _homeScreen, the rest should be widgets. – Melquiades 7 mins ago
Thanks for the fast help. I though I needed to call MaterialApp if I was building components outside of that original page. Thanks for the quick fix! just starting using flutter a few days ago

Related

Flutter - ListView scroll not working (bottom overflows by some pexels)

Flutter - While importing listview widget from one file then it just throws an error on the app's screen "Bottom overflowed by 500 pixels" but when if listview is directly used inside the home file it works fine. only throws error while importing listview widget from another file.
Here is the home file and the file which has listview widget
import 'package:flutter/material.dart';
import 'package:flutter_application_1/Pages/widgets/exercise_list.dart';
class Home extends StatelessWidget {
const Home({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: const [
ExerciseList()
],
),
),
);
}
}
Second file
import 'package:flutter/material.dart';
class ExerciseList extends StatelessWidget {
const ExerciseList({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return ListView(
shrinkWrap: true,
physics: const AlwaysScrollableScrollPhysics(),
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(10)),
padding: const EdgeInsets.all(5),
width: 150,
height: 135,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(5),
child: const Image(
image: NetworkImage(
"https://media.istockphoto.com/photos/man-lifting-weights-on-a-bench-press-picture-id180200014?b=1&k=20&m=180200014&s=170667a&w=0&h=VE9cTw0Pyus1IIENTjWxSkM9wyQhPFFIxikCpHDbwm8=")),
),
const SizedBox(
height: 8,
),
const Text(
"Chest Workout",
style:
TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
)
],
),
),
),
],
),
Row(
children: [
Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(10)),
padding: const EdgeInsets.all(5),
width: 150,
height: 135,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(5),
child: const Image(
image: NetworkImage(
"https://media.istockphoto.com/photos/man-lifting-weights-on-a-bench-press-picture-id180200014?b=1&k=20&m=180200014&s=170667a&w=0&h=VE9cTw0Pyus1IIENTjWxSkM9wyQhPFFIxikCpHDbwm8=")),
),
const SizedBox(
height: 8,
),
const Text(
"Chest Workout",
style:
TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
)
],
),
),
),
],
),
Row(
children: [
Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(10)),
padding: const EdgeInsets.all(5),
width: 150,
height: 135,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(5),
child: const Image(
image: NetworkImage(
"https://media.istockphoto.com/photos/man-lifting-weights-on-a-bench-press-picture-id180200014?b=1&k=20&m=180200014&s=170667a&w=0&h=VE9cTw0Pyus1IIENTjWxSkM9wyQhPFFIxikCpHDbwm8=")),
),
const SizedBox(
height: 8,
),
const Text(
"Chest Workout",
style:
TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
)
],
),
),
),
],
),
],
);
}
}
Do this:
import 'package:flutter/material.dart';
class ExerciseList extends StatelessWidget {
const ExerciseList({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
//wrap your listview with a constraint widget: i.e container or SizedBox
//give it some height of your choice and wrap with SingleChildScrollview //widget to prevent the overflow from occuring
return Scaffold(
body: SingleChildScrollView(
child: SizedBox(
height:
MediaQuery.of(context).size.height, // takes screen full height
child: ListView(
shrinkWrap: true,
scrollDirection: Axis.vertical,
//choose direction of your choice
physics: const BouncingScrollPhysics(),
// scroll effects not the actual scrolling
children: List.generate(10, (index) =>Row(
children: [
Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(10)),
padding: const EdgeInsets.all(5),
width: 150,
height: 135,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(5),
child: const Image(
image: NetworkImage(
"https://media.istockphoto.com/photos/man-lifting-weights-on-a-bench-press-picture-id180200014?b=1&k=20&m=180200014&s=170667a&w=0&h=VE9cTw0Pyus1IIENTjWxSkM9wyQhPFFIxikCpHDbwm8=")),
),
const SizedBox(
height: 8,
),
const Text(
"Chest Workout",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 14),
)
],
),
),
),
],
))
))),
);
}
}
in your main you don't need a column
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: const ExerciseList()
);
}
}
Try wrapping ExerciseList with SingleChildScrollView instead of Column:
class Home extends StatelessWidget {
const Home({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(20.0),
child: SingleChildScrollView(
child: ExerciseList(),
),
),
);
}
}
simply wrapped listview inside sizedbox and gave it a height of 150 and it's done we are good to go!☺☺
SizedBox(
child: ListView(
shrinkWrap: true,
physics: const AlwaysScrollableScrollPhysics(),
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(10)),
padding: const EdgeInsets.all(5),
width: 150,
height: 135,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(5),
child: const Image(
image: NetworkImage(
"https://media.istockphoto.com/photos/man-lifting-weights-on-a-bench-press-picture-id180200014?b=1&k=20&m=180200014&s=170667a&w=0&h=VE9cTw0Pyus1IIENTjWxSkM9wyQhPFFIxikCpHDbwm8=")),
),
const SizedBox(
height: 8,
),
const Text(
"Chest Workout",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 14),
)
],
),
),
),
],
),
Row(
children: [
Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(10)),
padding: const EdgeInsets.all(5),
width: 150,
height: 135,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(5),
child: const Image(
image: NetworkImage(
"https://media.istockphoto.com/photos/man-lifting-weights-on-a-bench-press-picture-id180200014?b=1&k=20&m=180200014&s=170667a&w=0&h=VE9cTw0Pyus1IIENTjWxSkM9wyQhPFFIxikCpHDbwm8=")),
),
const SizedBox(
height: 8,
),
const Text(
"Chest Workout",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 14),
)
],
),
),
),
],
),
Row(
children: [
Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(10)),
padding: const EdgeInsets.all(5),
width: 150,
height: 135,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(5),
child: const Image(
image: NetworkImage(
"https://media.istockphoto.com/photos/man-lifting-weights-on-a-bench-press-picture-id180200014?b=1&k=20&m=180200014&s=170667a&w=0&h=VE9cTw0Pyus1IIENTjWxSkM9wyQhPFFIxikCpHDbwm8=")),
),
const SizedBox(
height: 8,
),
const Text(
"Chest Workout",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 14),
)
],
),
),
),
],
),
],
));

Move Row Column to bottomCenter

How move Column wrap with Row to bottomCenter?
class DetailPage extends StatelessWidget {
const DetailPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: kBackgroundColor,
body: ListView(
padding: EdgeInsets.zero,
children: [
Stack(
children: [
destinationImage(),
contentImage(),
],
)
],
),
);
}
Widget destinationImage() {
return ShaderMask(
shaderCallback: (bounds) {
return LinearGradient(
begin: Alignment.center,
end: Alignment.bottomCenter,
colors: [
kWhiteColor,
Colors.black.withOpacity(0.80),
],
).createShader(bounds);
},
child: Container(
width: double.infinity,
height: 420.0,
decoration: const BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: AssetImage('assets/image_destination1.png'),
),
),
),
);
}
}
Widget contentImage() {
return Container(
padding: EdgeInsets.only(
left: defaultSideMargin,
bottom: 80.0,
right: defaultSideMargin,
),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Rialto Bridge',
style: whiteTextStyle.copyWith(
fontSize: 24.0,
fontWeight: semiBold,
),
),
Text(
'Italy',
style: whiteTextStyle.copyWith(
fontSize: 16.0,
fontWeight: light,
),
),
],
),
),
Container(
width: 24.0,
height: 24.0,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/icon_star.png'),
),
),
),
const SizedBox(width: 4.0),
Text(
'4.8',
style: blackTextStyle.copyWith(
fontSize: 14.0,
fontWeight: medium,
),
)
],
),
);
}
You can either use the alignment property on Stack widget.
Or you can wrap your contentImage() in a Positioned Widget
Try it on DartPad:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: DetailPage(),
);
}
}
class DetailPage extends StatelessWidget {
const DetailPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: ListView(
padding: EdgeInsets.zero,
children: [
Stack(
alignment: Alignment.topCenter,
children: [
destinationImage(),
Positioned(
bottom: 0,
child: contentImage(),
)
],
)
],
),
);
}
Widget destinationImage() {
return ShaderMask(
shaderCallback: (bounds) {
return LinearGradient(
begin: Alignment.center,
end: Alignment.bottomCenter,
colors: [
Colors.white,
Colors.black.withOpacity(0.80),
],
).createShader(bounds);
},
child:
Container(width: double.infinity, height: 420.0, color: Colors.green),
);
}
}
Widget contentImage() {
return Container(
padding: const EdgeInsets.only(bottom: 80.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text('Rialto Bridge'),
Text('Italy'),
],
),
Container(
width: 24.0,
height: 24.0,
color: Colors.amber,
),
const SizedBox(width: 4.0),
const Text('4.8')
],
),
);
}
Wrap contentImage into Positioned.fill
Stack(
children: [
destinationImage(),
Positioned.fill(child: contentImage()),
],
)
full code
class DetailPage extends StatelessWidget {
const DetailPage({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blue,
body: ListView(
padding: EdgeInsets.zero,
children: [
Stack(
children: [
destinationImage(),
Positioned.fill(child: contentImage()),
],
)
],
),
);
}
Widget destinationImage() {
return ShaderMask(
shaderCallback: (bounds) {
return LinearGradient(
begin: Alignment.center,
end: Alignment.bottomCenter,
colors: [
kWhiteColor,
Colors.black.withOpacity(0.80),
],
).createShader(bounds);
},
child: Container(
width: double.infinity,
height: 420.0,
decoration: const BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: AssetImage('assets/image_destination1.png'),
),
),
),
);
}
}
Widget contentImage() {
return Container(
padding: EdgeInsets.only(
left: defaultSideMargin,
bottom: 80.0,
right: defaultSideMargin,
),
child: Container(
color: Colors.red,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
color: Colors.white,
child: Align(
alignment: Alignment.bottomCenter,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Spacer(),
Text(
'Rialto Bridge',
style: whiteTextStyle.copyWith(
fontSize: 24.0,
fontWeight: semiBold,
),
),
Text(
'Italy',
style: whiteTextStyle.copyWith(
fontSize: 16.0,
fontWeight: light,
),
),
],
),
),
),
Container(
width: 24.0,
height: 24.0,
decoration: const BoxDecoration(
color: Colors.green,
image: DecorationImage(
image: AssetImage('assets/icon_star.png'),
),
),
),
const SizedBox(width: 4.0),
Text(
'4.8',
style: blackTextStyle.copyWith(
fontSize: 14.0,
fontWeight: FontWeight.w600,
),
)
],
),
),
);
}

Make Flutter Container Responsive

I am trying to make an app and I have used a container and a column widget under a stack widget but the width of the container and the positioned widget of a column widget are not updating according to the screen sizes.
Screenshot:
Please check the demo code given below and re-edit the code. Thank you.
code
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
var width = MediaQuery.of(context).size.width;
return Center(
child: Container(
height: 135,
width: width,
decoration: BoxDecoration(
border: Border.all(color: Colors.yellow),
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
child: Stack(
children: <Widget>[
Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Stack(
children: <Widget>[
Image.network(
'https://images3.alphacoders.com/823/82317.jpg',
fit: BoxFit.cover,
height: 120,
width: 120,
),
],
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 15, 5, 0),
child: Container(
width: width * 0.6,
height: 110,
child: const Text(
'product.name',
textAlign: TextAlign.justify,
style: TextStyle(fontSize: 17),
),
),
),
],
),
),
Positioned(
top: 80,
left: width * 0.85,
child: Column(
children: const [
Text(
'Rs200',
style:
TextStyle(fontSize: 17, fontWeight: FontWeight.bold),
),
Text(
'Rs300',
style: TextStyle(
decoration: TextDecoration.lineThrough,
fontSize: 17,
color: Colors.blueGrey),
),
],
),
),
],
)),
);
}
}
You should try this :
Container(
margin: EdgeInsets.all(16.0),
height: 135,
width: double.infinity,
decoration: BoxDecoration(
border: Border.all(color: Colors.yellow),
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
child: Stack(
children: <Widget>[
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Stack(
children: <Widget>[
Image.network(
'https://images3.alphacoders.com/823/82317.jpg',
fit: BoxFit.cover,
height: 120,
width: 120,
),
],
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(50, 15, 5, 0),
child: Container(
height: 110,
child: const Text(
'product.name',
textAlign: TextAlign.justify,
style: TextStyle(fontSize: 17),
),
),
),
],
),
),
Positioned(
top: 80,
right: 20,
child: Column(
children: const [
Text(
'Rs200',
style: TextStyle(
fontSize: 17, fontWeight: FontWeight.bold),
),
Text(
'Rs300',
style: TextStyle(
decoration: TextDecoration.lineThrough,
fontSize: 17,
color: Colors.blueGrey),
),
],
),
),
],
),
),
And your screen look like this -
There is no need to use of any Stack. I think you can do things using the row and column widget, check out the example that i have added below let me know if it work.
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
height: 135,
decoration: BoxDecoration(
border: Border.all(color: Colors.yellow),
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Stack(
children: <Widget>[
Image.network(
'https://images3.alphacoders.com/823/82317.jpg',
fit: BoxFit.cover,
height: 120,
width: 120,
),
],
),
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 15, 5, 0),
child: const Text(
'asdfnweoriwqer qweroiqwoer qweruqwoer sadfsdf dfsdf ',
textAlign: TextAlign.justify,
style: TextStyle(fontSize: 17),
),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: const [
Text(
'Rs200',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold),
),
Text(
'Rs300',
style: TextStyle(
decoration: TextDecoration.lineThrough,
fontSize: 17,
color: Colors.blueGrey),
),
],
),
),
],
),
],
),
),
],
)),
),
);
}
}
Layout Explanation:
There will be one row which will have two items 1) image and another will be a column.
Now the Column will have expanded widget to get max width.
Column childern will have two row widget one product name and another price row which will have Column as widget for text.
we have used row to take the max width.
For the Text to expand accordingly you have to add the expanded widget inside the row widget so that it scales based on the text that is coming.
Note : Please add padding according to your need.
Let me know if it works.
First of all, you have used so many redundant widgets which do not serve any purpose except making the code look ugly and complex. I have refactored the code and have used the least number of widgets while fulfilling your requirement:
Demo on the action: https://dartpad.dev/?null_safety=true&id=75d503fcbe2bdb0e8b37ff21fc284a30
Gist link: https://gist.github.com/omishah/75d503fcbe2bdb0e8b37ff21fc284a30 ( Do give star if this works for you. :) )
I have made the image also responsive which you can remove if you don't want to have it.
Complete code:
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final width = MediaQuery.of(context).size.width;
return Scaffold(
body: IntrinsicHeight(
child: Container(
margin: EdgeInsets.all(
8.0), // just to make the contianer stand out, you can remove it
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.yellow),
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Image.network(
'https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Image_created_with_a_mobile_phone.png/1200px-Image_created_with_a_mobile_phone.png',
fit: BoxFit.cover,
height:
width * 0.25, // 25% of screen width
width: width * 0.25,
),
),
SizedBox(width: 15),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'product.name',
style: TextStyle(fontSize: 17),
),
Align(
alignment: Alignment.centerRight,
child: Wrap(direction: Axis.vertical, children: [
Text(
'Rs200',
style: TextStyle(
fontSize: 17, fontWeight: FontWeight.bold),
),
Text(
'Rs300',
style: TextStyle(
decoration: TextDecoration.lineThrough,
fontSize: 17,
color: Colors.blueGrey),
),
]))
])),
],
),
)));
}
}

How to position elements independently using Stack, Row, and similar elements in Flutter

I have been trying to replicate these two designs in Flutter using Stack, Positioned, Row, and similar related widgets, however, I've been getting stuck in the same stages again and again. I either can't center the text or cannot position the back button correctly. Also, I am trying not to use fixed sizes/positions as this is supposed to be somewhat adaptable to different screen sizes.
Could someone point me in the right direction, of how to create this or similar layouts, which would be reused in other screens?
Example 1:
Example 2:
For your example numero 1, I came with this solution:
class DetailScreen extends StatefulWidget {
#override
_DetailScreenState createState() => _DetailScreenState();
}
class _DetailScreenState extends State<DetailScreen> {
#override
Widget build(BuildContext context) {
return Material(
color: Colors.white,
child: SafeArea(
child: Stack(
fit: StackFit.expand,
children: [
Container(
margin: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Color(0xFF0B2746),
borderRadius: BorderRadius.circular(15),
),
child: Container(
margin: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 18),
child: Text(
'Glossary',
style: TextStyle(
fontWeight: FontWeight.w800,
fontSize: 20,
),
),
)
],
),
),
),
Padding(
padding: const EdgeInsets.only(top: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Card(
margin: const EdgeInsets.only(left: 0),
child: Padding(
padding: const EdgeInsets.all(12),
child: Icon(Icons.arrow_back_ios),
),
elevation: 6,
),
],
),
)
],
),
),
);
}
}
and the result is the following:
For your second example, I had to add extra logic:
class DetailScreen extends StatefulWidget {
#override
_DetailScreenState createState() => _DetailScreenState();
}
class _DetailScreenState extends State<DetailScreen> {
#override
Widget build(BuildContext context) {
return Material(
color: Colors.white,
child: SafeArea(
child: Stack(
fit: StackFit.expand,
children: [
Container(
margin: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Color(0xFF0B2746),
borderRadius: BorderRadius.circular(15),
),
child: Column(
children: [
Container(
height: 64.0,
width: double.infinity,
margin: const EdgeInsets.only(left: 54, right: 8, top: 8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Row(
children: <Widget>[
SizedBox(width: 20),
Icon(Icons.train, size: 35),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 18),
child: Text(
'Metro',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.w800,
fontSize: 20,
),
),
),
),
Icon(Icons.arrow_drop_down, size: 35),
SizedBox(width: 20),
],
),
),
Expanded(
child: Container(
margin: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
)),
)
],
),
),
Padding(
padding: const EdgeInsets.only(top: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Card(
margin: const EdgeInsets.only(left: 0),
child: Padding(
padding: const EdgeInsets.all(12),
child: Icon(Icons.arrow_back_ios),
),
elevation: 6,
),
],
),
)
],
),
),
);
}
}
and the result for this one is the follwing:

How to stack items on top of each other?

i'm trying make a widget like image below.
Mindset of me is stack item into listview. The items are stacked. But when nesting a stack into listview, the stack needs to be wrapped in a fixed widget. If you remove the listview, you cannot make it into the list as in the picture. First time there is nothing wrong to expect people to ignore.
I hope to get the answer. Thanks.
body: Container(
color: Colors.white,
width: double.infinity,
child: SingleChildScrollView(
child: Stack(
children: <Widget>[
Positioned(top: 10,child: card1(),),
Positioned(bottom: 10,child: card1(),),
],
),
),
),
Item
static Widget card1() {
return Card(
elevation: 0,
child: Container(
margin: EdgeInsets.only(top: 100),
width: double.infinity,
padding: EdgeInsets.only(top: 18, left: 18),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(offset: Offset(0, 8), blurRadius: 8, spreadRadius: 0),
],
),
child: Stack(
children: <Widget>[
Container(
width: 343,
height: 196,
child: SvgPicture.asset(
"assets/bg.svg",
),
),
Container(
padding: EdgeInsets.only(
top: 24,
left: 24,
),
child: Row(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 10),
child: Text("Vietcombank"),
),
],
),
),
],
),
),
);
}
I created StackedListTile, you can try it (Demo here DartPad)
import 'package:flutter/material.dart';
class StackedListTile extends StatelessWidget {
final Color color;
final String title;
final ImageProvider iconImage;
const StackedListTile({
Key key,
#required this.color,
#required this.title,
#required this.iconImage,
}) : assert(color != null),
super(key: key);
#override
Widget build(BuildContext context) {
return SizedBox(
height: 90.0,
child: Stack(
children: <Widget>[
Container(
margin: const EdgeInsets.only(
left: 18.0,
top: 18.0,
right: 18.0,
),
padding: const EdgeInsets.only(
left: 25.0,
top: 25.0,
right: 25.0,
bottom: 10.0,
),
decoration: BoxDecoration(
color: color,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(8.0),
topRight: Radius.circular(8.0),
),
),
child: Row(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: AspectRatio(
aspectRatio: 1,
child: Container(
color: Colors.white,
child: Image(
image: iconImage,
fit: BoxFit.cover,
),
),
),
),
const SizedBox(width: 5.0),
Expanded(
child: Text(
title,
style: const TextStyle(
color: Colors.white,
letterSpacing: 1.0,
),
),
),
//TODO: Add other stuff here
const Icon(
Icons.arrow_forward_ios,
color: Colors.white,
size: 20.0,
),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 4.0,
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Colors.transparent, Colors.black12],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
),
),
],
),
);
}
}
Usage:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: MainPage(),
debugShowCheckedModeBanner: false,
),
);
}
class MainPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Demo")),
body: ListView(
children: <Widget>[
StackedListTile(
title: "Techcombank1",
color: Colors.blue[600],
//iconImage: AssetImage("assets/images/1.png"), //TODO: Use this for asset images
iconImage: NetworkImage(
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQfo2BL_di4IK1AuHOS4y_16BatmqdkOlcB1JBjJK2zK9sUvZ2FUg&s",
),
),
StackedListTile(
title: "Techcombank2",
color: Colors.red[600],
iconImage: NetworkImage("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQNvzXsqFidC5YqNrKHEJGt1kyC99dJ_EWt_Bcc5dyy4rNGzFk8yQ&s"),
),
StackedListTile(
title: "Techcombank3",
color: Colors.green[600],
iconImage: NetworkImage("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQNvzXsqFidC5YqNrKHEJGt1kyC99dJ_EWt_Bcc5dyy4rNGzFk8yQ&s"),
),
for(int i =0; i<100; i++)
StackedListTile(
title: "Item_$i",
color: Colors.amber.withOpacity(1-(i%10)/10),
iconImage: NetworkImage("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQNvzXsqFidC5YqNrKHEJGt1kyC99dJ_EWt_Bcc5dyy4rNGzFk8yQ&s"),
),
],
),
);
}
}
Try to use SliverToBoxAdapter
body: return Container(
color: Colors.white,
width: double.infinity,
child: SingleChildScrollView(
child: SliverToBoxAdapter(
child: Stack(
children: <Widget>[
Positioned(
top: 10,
child: card1(),
),
Positioned(
bottom: 10,
child: card1(),
),
],
),
),
),
),