Flutter / Examples / * Project 1: Traveling App UI Design
Traveling App UI
-
1. Main Page
Source:
https://www.youtube.com/watch?v=YlgzSH_DPDo
UI1. Main page
1. Container : for bg image
2. SafeArea
3. Padding
4. Column: divide the body into vertical 3 rows using Column()
file: main.dart
2. welcom screenimport 'package:flutter/material.dart'; import 'package:a/screens/WelcomeScreen.dart'; import 'dart:ui'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { double screenWidth = window.physicalSize.width; return MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData( scaffoldBackgroundColor: Color(0xffffff) ), home: WelcomeScreen(), ); } } file: screens/WelcomeScreen.dart
1. minimal code
1. Container : for bg image
import 'package:flutter/material.dart'; class WelcomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Container( ); } } 2. add bg image
file: screens/WelcomeScreen.dart
import 'package:flutter/material.dart'; class WelcomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('images/bg1.png'), fit: BoxFit.cover, opacity: 0.7 ) ), ); } } BoxDecoration 3. add screen body
file: screens/WelcomeScreen.dart
1. Column() : for 3 rows
import 'package:flutter/material.dart'; class WelcomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('images/bg1.png'), fit: BoxFit.cover, opacity: 0.7 ) ), child :SafeArea( child: Padding( padding: EdgeInsets.symmetric(vertical: 65,horizontal: 25), child: Column( children: [ Text( 'Enjoy', style: TextStyle( color: Colors.white, fontSize: 35, fontWeight: FontWeight.bold, letterSpacing: 1.5 ), ) ], ), ), ) ); } } import 'package:flutter/material.dart'; class WelcomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('images/bg1.png'), fit: BoxFit.cover, opacity: 0.7 ) ), child :SafeArea( child: Padding( padding: EdgeInsets.symmetric(vertical: 65,horizontal: 25), child: Column( children: [ Text( 'Enjoy', style: TextStyle( color: Colors.white, fontSize: 35, fontWeight: FontWeight.bold, letterSpacing: 1.5 ), ), SizedBox(height: 2,), Text( 'Enjoy', style: TextStyle( color: Colors.white.withOpacity(0.7), fontSize: 35, fontWeight: FontWeight.w400, letterSpacing: 1.5 ), ), SizedBox(height: 2,), ], ), ), ) ); } } 3. align text left
use crossAxisAlignment: CrossAxisAlignment.start, to column
child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ 4. add button
file: screens/WelcomeScreen.dart
import 'package:flutter/material.dart'; class WelcomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('images/bg1.png'), fit: BoxFit.cover, opacity: 0.7 ) ), child :SafeArea( child: Padding( padding: EdgeInsets.symmetric(vertical: 65,horizontal: 25), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Enjoy', style: TextStyle( color: Colors.white, fontSize: 35, fontWeight: FontWeight.bold, letterSpacing: 1.5 ), ), SizedBox(height: 2,), Text( 'Enjoy', style: TextStyle( color: Colors.white.withOpacity(0.7), fontSize: 35, fontWeight: FontWeight.w400, letterSpacing: 1.5 ), ), SizedBox(height: 2,), InkWell( onTap: () { print('InkWell 2 tapped!'); }, child: Container( padding: const EdgeInsets.all(12.0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8.0), color: Colors.red, ), child: const Text( 'InkWell 2', style: TextStyle( color: Colors.white, fontSize: 18.0, ), ), ), ), ], ), ), ) ); } } Error: we will get error ' no material widget found' solutionadd material widget and move the safearea into material widget
Navigationimport 'package:flutter/material.dart'; class WelcomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('images/bg1.png'), fit: BoxFit.cover, opacity: 0.7 ) ), child:Material( color: Colors.transparent, child :SafeArea( child: Padding( padding: EdgeInsets.symmetric(vertical: 65,horizontal: 25), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Enjoy', style: TextStyle( color: Colors.white, fontSize: 35, fontWeight: FontWeight.bold, letterSpacing: 1.5 ), ), SizedBox(height: 2,), Text( 'Enjoy', style: TextStyle( color: Colors.white.withOpacity(0.7), fontSize: 35, fontWeight: FontWeight.w400, letterSpacing: 1.5 ), ), SizedBox(height: 2,), InkWell( onTap: () { print('InkWell 2 tapped!'); }, child: Container( padding: const EdgeInsets.all(12.0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8.0), color: Colors.red, ), child: const Text( 'InkWell 2', style: TextStyle( color: Colors.white, fontSize: 18.0, ), ), ), ), ], ), ), ) ) ); } } onTap: () { print('InkWell 2 tapped!'); Navigator.push(context, MaterialPageRoute( builder: (context) => HomePage() )); }, -
2. Home Page
1. home page header
file: screens/HomePage.dart
import 'package:flutter/material.dart'; import 'package:a/widgets/home_app_bar.dart'; class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: PreferredSize( preferredSize: Size.fromHeight(90.0), child: HomeAppBar(), ), ); } } where HomeAppBar is widget 2. widgets : header widget
widgets/home_app_bar.dart
1. Row(): divide the header into 3 horizontal cells using Row()
2. Row(): divide the 2nd cell into 2 cells using Row()
1. minimal code
import 'package:flutter/material.dart'; class WelcomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Padding( padding: EdgeInsets.all(20), ); } } 2. add header elements
import 'package:flutter/material.dart'; class HomeAppBar extends StatelessWidget { @override Widget build(BuildContext context) { return Padding( padding: EdgeInsets.all(20), child:Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ InkWell( onTap: (){ }, child: Container( padding: EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black26, blurRadius: 6 ) ], borderRadius: BorderRadius.circular(20) ), child:Icon( Icons.sort_rounded, size: 28, ) ), ) ], ) ); } } import 'package:flutter/material.dart'; class HomeAppBar extends StatelessWidget { @override Widget build(BuildContext context) { return Padding( padding: EdgeInsets.all(20), child:Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ InkWell( onTap: (){ }, child: Container( padding: EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black26, blurRadius: 6 ) ], borderRadius: BorderRadius.circular(20) ), child:Icon( Icons.sort_rounded, size: 28, ) ), ), Row( children: [ Icon( Icons.location_on, color: Color(0xFFF655959) ), Text( 'Newyork', style: TextStyle( fontSize: 18, fontWeight: FontWeight.w500 ), ) ], ), InkWell( onTap: (){ }, child: Container( padding: EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black26, blurRadius: 6 ) ], borderRadius: BorderRadius.circular(20) ), child:Icon( Icons.search, size: 28, ) ), ), ], ) ); } } 3. home page body
1. SingleChildScrollView : for screen scrolling
2. Column : for row creation
3. Expanded : fit to the sceen
4. Container : for alignment, rounded edges, bg image, decorations etc.
1. list view
2. InkWell : for onTap
3. container : for bg image
4. column : for multiple rows
5. container: for alignment
Create ListView structure
import 'package:flutter/material.dart'; import 'package:a/widgets/home_app_bar.dart'; class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: PreferredSize( preferredSize: Size.fromHeight(90.0), child: HomeAppBar(), ), body: SafeArea( child: Padding( padding: EdgeInsets.symmetric(vertical: 30), child: SingleChildScrollView( child: Column( children: [ Expanded( child: Container( height: 200, child: ListView.builder( itemCount: 6, scrollDirection: Axis.horizontal, shrinkWrap: true, itemBuilder: (BuildContext context, int index){ } ), ) ) ], ), ) ) ) ); } } Error: getting error due to Expanded() widget inside the Column() widget Solution: use Row() inside Column(). then use Expanded() inside Row() modify the above code
import 'package:flutter/material.dart'; import 'package:a/widgets/home_app_bar.dart'; class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: PreferredSize( preferredSize: Size.fromHeight(90.0), child: HomeAppBar(), ), body: SafeArea( child: Padding( padding: EdgeInsets.symmetric(vertical: 30), child: SingleChildScrollView( child: Column( children: [ //************************************ */ //modified : added Row() //************************************ */ Row( children: [ Expanded( child: Container( height: 200, child: ListView.builder( itemCount: 6, scrollDirection: Axis.horizontal, shrinkWrap: true, itemBuilder: (BuildContext context, int index){ } ), ) ) ] ) ], ), ) ) ) ); } } set clickable bg image
1.InkWell : for onTap
2. container : for bg image
import 'package:flutter/material.dart'; import 'package:a/widgets/home_app_bar.dart'; class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: PreferredSize( preferredSize: Size.fromHeight(90.0), child: HomeAppBar(), ), body: SafeArea( child: Padding( padding: EdgeInsets.symmetric(vertical: 30), child: SingleChildScrollView( child: Column( children: [ Expanded( child: Container( height: 200, child: ListView.builder( itemCount: 6, scrollDirection: Axis.horizontal, shrinkWrap: true, itemBuilder: (BuildContext context, int index){ return InkWell( onTap: (){}, child: Container( width:160, padding:EdgeInsets.all(20), margin: EdgeInsets.only(left: 15), decoration: BoxDecoration( color: Colors.black, borderRadius: BorderRadius.circular(15), image: DecorationImage( image: AssetImage("images/city${index+1}.jpg"), fit : BoxFit.cover, opacity: 0.7 ) ), ) ); } ), ) ) ], ), ) ) ) ); } } add content
import 'package:flutter/material.dart'; import 'package:a/widgets/home_app_bar.dart'; class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: PreferredSize( preferredSize: Size.fromHeight(90.0), child: HomeAppBar(), ), body: SafeArea( child: Padding( padding: EdgeInsets.symmetric(vertical: 30), child: SingleChildScrollView( child: Column( children: [ Expanded( child: Container( height: 200, child: ListView.builder( itemCount: 6, scrollDirection: Axis.horizontal, shrinkWrap: true, itemBuilder: (BuildContext context, int index){ return InkWell( onTap: (){}, child: Container( width:160, padding:EdgeInsets.all(20), margin: EdgeInsets.only(left: 15), decoration: BoxDecoration( color: Colors.black, borderRadius: BorderRadius.circular(15), image: DecorationImage( image: AssetImage("images/city${index+1}.jpg"), fit : BoxFit.cover, opacity: 0.7 ) ), child: Column( children: [ Container( alignment: Alignment.topRight, child: Icon( Icons.bookmark_border_outlined, color: Colors.white, size:30 ), ), Container( alignment: Alignment.bottomLeft, child: Text( "City Name", style: TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600 ), ) ) ], ) ) ); } ), ) ) ], ), ) ) ) ); } } 1. the text 'City Name' does not show leftBottom of the widget
solution: use Spacer() between the container
2. horizontal buttonschild: Column( children: [ Container( alignment: Alignment.topRight, child: Icon( Icons.bookmark_border_outlined, color: Colors.white, size:30 ), ), //************************************ */ //added spacer //************************************ */ Spacer(), Container( alignment: Alignment.bottomLeft, child: Text( "City Name", style: TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600 ), ) ) ], ) 1. SingleChildScrollView : for scrolling
2. padding: for surronding paddings
3. Row : for horizontal cells
4. container : for decoration, shadow
import 'package:flutter/material.dart'; import 'package:a/widgets/home_app_bar.dart'; class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: PreferredSize( preferredSize: Size.fromHeight(90.0), child: HomeAppBar(), ), body: SafeArea( child: Padding( padding: EdgeInsets.symmetric(vertical: 30), child: SingleChildScrollView( child: Column( children: [ Row( children: [ Expanded( child: Container( height: 200, child: ListView.builder( itemCount: 6, scrollDirection: Axis.horizontal, shrinkWrap: false, itemBuilder: (BuildContext context, int index){ return InkWell( onTap: (){}, child: Container( width:160, padding:EdgeInsets.all(20), margin: EdgeInsets.only(left: 15), decoration: BoxDecoration( color: Colors.black, borderRadius: BorderRadius.circular(15), image: DecorationImage( image: AssetImage("images/bg.jpg"), fit : BoxFit.cover, opacity: 0.7 ) ), child: Column( children: [ Container( alignment: Alignment.topRight, child: Icon( Icons.bookmark_border_outlined, color: Colors.white, size:30 ), ), Spacer(), Container( alignment: Alignment.bottomLeft, child: Text( "City Name", style: TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600 ), ) ) ], ) ) ); } ), ) ), ], ), SizedBox(height: 20,), SingleChildScrollView( scrollDirection: Axis.horizontal, child: Padding( padding: EdgeInsets.all(8), child: Row( children: [ Container( margin: EdgeInsets.symmetric(horizontal: 10), padding: EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), boxShadow: [ BoxShadow( color: Colors.red, blurRadius: 4 ) ] ), child: Text( "Best Price", style: TextStyle( color: Colors.white ), ), ) ], ), ), ) ], ), ) ) ) ); } } use for loop for multiple containers
3. Image listingSizedBox(height: 20,), SingleChildScrollView( scrollDirection: Axis.horizontal, child: Padding( padding: EdgeInsets.all(8), child: Row( children: [ //************************************ */ //added for loop //************************************ */ for(int i=0;i<6;i++) Container( margin: EdgeInsets.symmetric(horizontal: 10), padding: EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), boxShadow: [ BoxShadow( color: Colors.red, blurRadius: 4 ) ] ), child: Text( "Best Price", style: TextStyle( color: Colors.red ), ), ) ], ), ), ) 1. listView
2. padding : for surrounding padding
3. InkWell : for onTap
4. Container: for bg image, decorations
Add the image listing in the Column() after the SingleChildScrollView()
SizedBox(height: 20,), ListView.builder( physics:NeverScrollableScrollPhysics() , shrinkWrap: true, itemCount: 6, itemBuilder: (BuildContext context, int index) { return Padding( padding: EdgeInsets.all(15), child: InkWell( onTap: (){}, child: Container( height: 200, decoration: BoxDecoration( color: Colors.black, borderRadius: BorderRadius.circular(15), image: DecorationImage( image: AssetImage("images/bg.jpg"), fit: BoxFit.cover, opacity: 0.8 ) ), ) ) ); } ) fit: BoxFit.cover : fit the iamge to the container Add image title and right tool
1. Add Column() inside Padding() and move the InkWell() to the Column()
2. Add Row() to show the title at left side and more tool at right side
ListView.builder( physics:NeverScrollableScrollPhysics() , shrinkWrap: true, itemCount: 6, itemBuilder: (BuildContext context, int index) { return Padding( padding: EdgeInsets.all(15), //************************************ */ //modified the code : added Colunm() //************************************ */ child: Column( children: [ InkWell( onTap: (){}, child: Container( height: 200, decoration: BoxDecoration( color: Colors.black, borderRadius: BorderRadius.circular(15), image: DecorationImage( image: AssetImage("images/bg.jpg"), fit: BoxFit.cover, opacity: 0.8 ) ), ) ), //************************************ */ //added new code //************************************ */ Padding( padding: EdgeInsets.only(top:10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "City Name", style: TextStyle( fontSize: 20, fontWeight: FontWeight.w600 ), ), Icon(Icons.more_vert, size:30, color:Colors.red) ], ), ) ], ) ); } ) add star and rating value
1. Row() for two cells
4 BottomNavBarListView.builder( physics:NeverScrollableScrollPhysics() , shrinkWrap: true, itemCount: 6, itemBuilder: (BuildContext context, int index) { return Padding( padding: EdgeInsets.all(15), child: Column( children: [ InkWell( onTap: (){}, child: Container( height: 200, decoration: BoxDecoration( color: Colors.black, borderRadius: BorderRadius.circular(15), image: DecorationImage( image: AssetImage("images/bg.jpg"), fit: BoxFit.cover, opacity: 0.8 ) ), ) ), Padding( padding: EdgeInsets.only(top:10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "City Name", style: TextStyle( fontSize: 20, fontWeight: FontWeight.w600 ), ), Icon(Icons.more_vert, size:30, color:Colors.red) ], ), ), //************************************ */ //added new code //************************************ */ SizedBox(height: 20,), Row( children: [ Icon( Icons.star, size: 20, color: Colors.red, ), Text( "4.5", style: TextStyle( fontWeight: FontWeight.w500 ), ) ], ) ], ) ); } ) add NavBar after SafeArea()
return Scaffold( appBar: PreferredSize( preferredSize: Size.fromHeight(90.0), child: HomeAppBar(), ), body: SafeArea( child: Padding( padding: EdgeInsets.symmetric(vertical: 30), child: SingleChildScrollView( child: Column( children: [ Row( children: [ Expanded( child: Container( height: 200, child: ListView.builder( itemCount: 6, scrollDirection: Axis.horizontal, shrinkWrap: false, itemBuilder: (BuildContext context, int index){ return InkWell( onTap: (){}, child: Container( width:160, padding:EdgeInsets.all(20), margin: EdgeInsets.only(left: 15), decoration: BoxDecoration( color: Colors.black, borderRadius: BorderRadius.circular(15), image: DecorationImage( image: AssetImage("images/bg.jpg"), fit : BoxFit.cover, opacity: 0.7 ) ), child: Column( children: [ Container( alignment: Alignment.topRight, child: Icon( Icons.bookmark_border_outlined, color: Colors.white, size:30 ), ), Spacer(), Container( alignment: Alignment.bottomLeft, child: Text( "City Name", style: TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600 ), ) ) ], ) ) ); } ), ) ), ], ), SizedBox(height: 20,), SingleChildScrollView( scrollDirection: Axis.horizontal, child: Padding( padding: EdgeInsets.all(8), child: Row( children: [ for(int i=0;i<6;i++) Container( margin: EdgeInsets.symmetric(horizontal: 10), padding: EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), boxShadow: [ BoxShadow( color: Colors.red, blurRadius: 4 ) ] ), child: Text( "Best Price", style: TextStyle( color: Colors.red ), ), ) ], ), ), ), SizedBox(height: 20,), ListView.builder( physics:NeverScrollableScrollPhysics() , shrinkWrap: true, itemCount: 6, itemBuilder: (BuildContext context, int index) { return Padding( padding: EdgeInsets.all(15), child: Column( children: [ InkWell( onTap: (){}, child: Container( height: 200, decoration: BoxDecoration( color: Colors.black, borderRadius: BorderRadius.circular(15), image: DecorationImage( image: AssetImage("images/bg.jpg"), fit: BoxFit.cover, opacity: 0.8 ) ), ) ), Padding( padding: EdgeInsets.only(top:10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "City Name", style: TextStyle( fontSize: 20, fontWeight: FontWeight.w600 ), ), Icon(Icons.more_vert, size:30, color:Colors.red) ], ), ), SizedBox(height: 20,), Row( children: [ Icon( Icons.star, size: 20, color: Colors.red, ), Text( "4.5", style: TextStyle( fontWeight: FontWeight.w500 ), ) ], ) ], ) ); } ) ], ), ) ) ), //end of safeArea //***************************** */ // added new code */ //**************************** */ bottomNavigationBar: HomeBottomBar(), ); 5. widget: HomeBottomBar
widgets/home_bottom_bar.dart
import 'package:flutter/material.dart'; class HomeBottomBar extends StatelessWidget { @override Widget build(BuildContext context) { return Container(); } } add package 'curved_navigation_bar ' into pubspec.yaml
Add icons
import 'package:curved_navigation_bar/curved_navigation_bar.dart'; import 'package:flutter/material.dart'; class HomeBottomBar extends StatelessWidget { @override Widget build(BuildContext context) { return CurvedNavigationBar( backgroundColor: Colors.transparent, items:[ Icon( Icons.person_3_outlined, size:30 ), Icon( Icons.favorite_outline, size:30 ), Icon( Icons.home, size:30 ), Icon( Icons.list, size:30 ) ] ); } } 5. add navigation link
onTap: (){ Navigator.push(context, MaterialPageRoute( builder: (context) => PostScreen() )); }, -
3. Post Screen
1. PostScreen
1. set screen bg imagescreens/post_screen.dart
1. container() : for setting bg image
2. add header barimport 'package:flutter/material.dart'; class PostPage extends StatelessWidget { @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( image:DecorationImage( image: AssetImage("images/bg.jpg"), fit: BoxFit.cover, opacity:0.8 ), ) ); } } screens/post_screen.dart
1. Scaffold() : for appBar
2. PreferredSize : for custom header
3. PostAppBar widgetimport 'package:flutter/material.dart'; class PostPage extends StatelessWidget { @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( image:DecorationImage( image: AssetImage("images/bg.jpg"), fit: BoxFit.cover, opacity:0.8 ), ), //* **************/ //added new code // //**************** */ child: Scaffold( backgroundColor: Colors.transparent, appBar: PreferredSize( preferredSize: Size.fromHeight(90), child: PostAppBar() ), ), ); } } widgets/post_app_bar.dart
import 'package:flutter/material.dart'; class PostAppBar extends StatelessWidget { @override Widget build(BuildContext context) { return Container(); } } 1. add header icons : widgets/post_app_bar.dart
1. Padding
2.Row for 2 cells
3. InkWell : for navigation
4. container : for decoration, shadow
3. Post Screen Bodyimport 'package:flutter/material.dart'; class PostAppBar extends StatelessWidget { @override Widget build(BuildContext context) { //********************* */ // added new code / //*********************** */ return Padding( padding: EdgeInsets.all(20), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ InkWell( onTap: (){ Navigator.pop(context); }, child: Container( alignment: Alignment.center, padding: EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( color: Colors.white, blurRadius: 6 ) ] ), child: Icon( Icons.arrow_back_ios, size:28 ), ), ) ], ), ); } } file: screens/post_screen.dart
add bottomNavigationBar
2. create PostBottomBar widgetimport 'package:flutter/material.dart'; import 'package:a/widgets/post_app_bar.dart'; import 'package:a/widgets/post_bottom_bar.dart'; class PostPage extends StatelessWidget { @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( image:DecorationImage( image: AssetImage("images/bg.jpg"), fit: BoxFit.cover, opacity:0.8 ), ), child: Scaffold( backgroundColor: Colors.transparent, appBar: PreferredSize( preferredSize: Size.fromHeight(90), child: PostAppBar() ), bottomNavigationBar: PostBottomBar(), ), ); } } file: widgets/post_bottom_bar.dart
1. add bottom body
import 'package:flutter/material.dart'; class PostBottomBar extends StatelessWidget { @override Widget build(BuildContext context) { return Container( height: MediaQuery.of(context).size.height/2, padding: EdgeInsets.only(top:20, left:20, right:20), decoration: BoxDecoration( color: Color(0xFFEDF2F6), borderRadius: BorderRadius.only( topLeft: Radius.circular(40), topRight: Radius.circular(40) ) ) , ); } } 2. add first row
1. listView() : for scrolling
2. Column() : for multiple rows
3. Row() : for left text and right cell
4. again Row() in the right cell for text and star value
import 'package:flutter/material.dart'; class PostBottomBar extends StatelessWidget { @override Widget build(BuildContext context) { return Container( height: MediaQuery.of(context).size.height/2, padding: EdgeInsets.only(top:20, left:20, right:20), decoration: BoxDecoration( color: Color(0xFFEDF2F6), borderRadius: BorderRadius.only( topLeft: Radius.circular(40), topRight: Radius.circular(40) ) ) , /********************************* */ // added new code // //****************************** */ child: ListView( children: [ Padding( padding: EdgeInsets.only(), child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "City Name, Country", style: TextStyle( fontWeight: FontWeight.w600, fontSize: 23 ), ), Row( children: [ Icon( Icons.star, color:Colors.amber, size:25 ), Text( "4.5" ) ], ) ], ) ], ), ) ], ), ); } } 3. add second row
import 'package:flutter/material.dart'; class PostBottomBar extends StatelessWidget { @override Widget build(BuildContext context) { return Container( height: MediaQuery.of(context).size.height/2, padding: EdgeInsets.only(top:20, left:20, right:20), decoration: BoxDecoration( color: Color(0xFFEDF2F6), borderRadius: BorderRadius.only( topLeft: Radius.circular(40), topRight: Radius.circular(40) ) ) , child: ListView( children: [ Padding( padding: EdgeInsets.only(), child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "City Name, Country", style: TextStyle( fontWeight: FontWeight.w600, fontSize: 23 ), ), Row( children: [ Icon( Icons.star, color:Colors.amber, size:25 ), Text( "4.5" ) ], ) ], ), //************************ */ // added new code // /******************************* */ SizedBox(height: 20,), Text( "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum", textAlign: TextAlign.justify, ) ], ), ) ], ), ); } } 4. add third row
import 'package:flutter/material.dart'; class PostBottomBar extends StatelessWidget { @override Widget build(BuildContext context) { return Container( height: MediaQuery.of(context).size.height/2, padding: EdgeInsets.only(top:20, left:20, right:20), decoration: BoxDecoration( color: Color(0xFFEDF2F6), borderRadius: BorderRadius.only( topLeft: Radius.circular(40), topRight: Radius.circular(40) ) ) , child: ListView( children: [ Padding( padding: EdgeInsets.only(), child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "City Name, Country", style: TextStyle( fontWeight: FontWeight.w600, fontSize: 23 ), ), Row( children: [ Icon( Icons.star, color:Colors.amber, size:25 ), Text( "4.5" ) ], ) ], ), SizedBox(height: 20,), Text( "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum", textAlign: TextAlign.justify, ), //********** */ // added new code // //**************************** */ SizedBox(height: 20,), Row( children: [ Padding( padding: EdgeInsets.only(right:5), child: Expanded( child: ClipRRect( borderRadius: BorderRadius.circular(15), child: Image.asset( "images/bg.jpg", fit: BoxFit.cover, width: 120, height: 90, ), ), ), ) ], ) ], ), ) ], ), ); } } 5. add third row last image
1. expanded for fit the image to the container
2. container for decoration and image
import 'package:flutter/material.dart'; class PostBottomBar extends StatelessWidget { @override Widget build(BuildContext context) { return Container( height: MediaQuery.of(context).size.height/2, padding: EdgeInsets.only(top:20, left:20, right:20), decoration: BoxDecoration( color: Color(0xFFEDF2F6), borderRadius: BorderRadius.only( topLeft: Radius.circular(40), topRight: Radius.circular(40) ) ) , child: ListView( children: [ Padding( padding: EdgeInsets.only(), child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "City Name, Country", style: TextStyle( fontWeight: FontWeight.w600, fontSize: 23 ), ), Row( children: [ Icon( Icons.star, color:Colors.amber, size:25 ), Text( "4.5" ) ], ) ], ), SizedBox(height: 20,), Text( "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum", textAlign: TextAlign.justify, ), SizedBox(height: 20,), Row( children: [ Padding( padding: EdgeInsets.only(right:5), child: Expanded( child: ClipRRect( borderRadius: BorderRadius.circular(15), child: Image.asset( "images/bg.jpg", fit: BoxFit.cover, width: 120, height: 90, ), ), ), ), Padding( padding: EdgeInsets.only(right:5), child: Expanded( child: ClipRRect( borderRadius: BorderRadius.circular(15), child: Image.asset( "images/bg.jpg", fit: BoxFit.cover, width: 120, height: 90, ), ), ), ), //************ */ // added new code // //****************************** */ Expanded( child: Container( alignment: Alignment.center, width: 120, height: 90, margin: EdgeInsets.only(right:5), decoration: BoxDecoration( color: Colors.black26, borderRadius: BorderRadius.circular(15), image: DecorationImage( image:AssetImage("images/bg.jpg"), fit: BoxFit.cover, opacity:0.4 ) ), child: Text( "10+" ), ), ) ], ) ], ), ) ], ), ); } } 5. add 4th row
import 'package:flutter/material.dart'; class PostBottomBar extends StatelessWidget { @override Widget build(BuildContext context) { return Container( height: MediaQuery.of(context).size.height/2, padding: EdgeInsets.only(top:20, left:20, right:20), decoration: BoxDecoration( color: Color(0xFFEDF2F6), borderRadius: BorderRadius.only( topLeft: Radius.circular(40), topRight: Radius.circular(40) ) ) , child: ListView( children: [ Padding( padding: EdgeInsets.only(), child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "City Name, Country", style: TextStyle( fontWeight: FontWeight.w600, fontSize: 23 ), ), Row( children: [ Icon( Icons.star, color:Colors.amber, size:25 ), Text( "4.5" ) ], ) ], ), SizedBox(height: 20,), Text( "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum", textAlign: TextAlign.justify, ), SizedBox(height: 20,), Row( children: [ Padding( padding: EdgeInsets.only(right:5), child: Expanded( child: ClipRRect( borderRadius: BorderRadius.circular(15), child: Image.asset( "images/bg.jpg", fit: BoxFit.cover, width: 120, height: 90, ), ), ), ), Padding( padding: EdgeInsets.only(right:5), child: Expanded( child: ClipRRect( borderRadius: BorderRadius.circular(15), child: Image.asset( "images/bg.jpg", fit: BoxFit.cover, width: 120, height: 90, ), ), ), ), Expanded( child: Container( alignment: Alignment.center, width: 120, height: 90, margin: EdgeInsets.only(right:5), decoration: BoxDecoration( color: Colors.black26, borderRadius: BorderRadius.circular(15), image: DecorationImage( image:AssetImage("images/bg.jpg"), fit: BoxFit.cover, opacity:0.4 ) ), child: Text( "10+" ), ), ), ], ), //*********************** */ // added new code // //********************* */ SizedBox(height: 15,), Container( height: 80, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Container( padding: EdgeInsets.all(10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black26, blurRadius: 6 ) ] ), child: Icon( Icons.bookmark_border_outlined ), ) ], ), ) ], ), ) ], ), ); } } import 'package:flutter/material.dart'; class PostBottomBar extends StatelessWidget { @override Widget build(BuildContext context) { return Container( height: MediaQuery.of(context).size.height/2, padding: EdgeInsets.only(top:20, left:20, right:20), decoration: BoxDecoration( color: Color(0xFFEDF2F6), borderRadius: BorderRadius.only( topLeft: Radius.circular(40), topRight: Radius.circular(40) ) ) , child: ListView( children: [ Padding( padding: EdgeInsets.only(), child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "City Name, Country", style: TextStyle( fontWeight: FontWeight.w600, fontSize: 23 ), ), Row( children: [ Icon( Icons.star, color:Colors.amber, size:25 ), Text( "4.5" ) ], ) ], ), SizedBox(height: 20,), Text( "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum", textAlign: TextAlign.justify, ), SizedBox(height: 20,), Row( children: [ Padding( padding: EdgeInsets.only(right:5), child: Expanded( child: ClipRRect( borderRadius: BorderRadius.circular(15), child: Image.asset( "images/bg.jpg", fit: BoxFit.cover, width: 120, height: 90, ), ), ), ), Padding( padding: EdgeInsets.only(right:5), child: Expanded( child: ClipRRect( borderRadius: BorderRadius.circular(15), child: Image.asset( "images/bg.jpg", fit: BoxFit.cover, width: 120, height: 90, ), ), ), ), Expanded( child: Container( alignment: Alignment.center, width: 120, height: 90, margin: EdgeInsets.only(right:5), decoration: BoxDecoration( color: Colors.black26, borderRadius: BorderRadius.circular(15), image: DecorationImage( image:AssetImage("images/bg.jpg"), fit: BoxFit.cover, opacity:0.4 ) ), child: Text( "10+" ), ), ), ], ), //******************************** */ //added new code // //******************************** */ SizedBox(height: 15,), Container( height: 80, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Container( padding: EdgeInsets.all(10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black26, blurRadius: 6 ) ] ), child: Icon( Icons.bookmark_border_outlined ), ), Container( padding: EdgeInsets.all(10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.redAccent, boxShadow: [ BoxShadow( color: Colors.black26, blurRadius: 6 ) ] ), child: Text( "Book Now", style: TextStyle( color:Colors.white, fontSize: 28, fontWeight: FontWeight.w600 ), ), ), ], ), ) ], ), ) ], ), ); } }