Related
I'm a beginner at app dev and I'm trying out flutter. I'm currently having a problem with positioning my background on the project that I am currently testing out.I'm following a UI kit that I am trying to copy for the purpose of practicing, but I am having problem with the UI.
I tried using stack but the whole screen is wrapped with its children and not taking up space. it looks like this:
and this is what I wanted to do:
This is the background that I wanted to put in my app, it is not literally a background or wallpaper because of its size. I just needed this to be placed at the bottom of the screen or background:
this is the code that I currently have:
import 'package:audit_finance_app/constant/theme.dart';
import 'package:audit_finance_app/widgets/widgets.dart';
import 'package:audit_finance_app/screens/homescreen.dart';
import 'package:flutter/material.dart';
import 'dart:math' as math;
class SignInPage extends StatefulWidget {
const SignInPage({super.key});
#override
State<SignInPage> createState() => _SignInPageState();
}
class _SignInPageState extends State<SignInPage> {
late List<String> inputPass;
String defaultPass = '1234';
#override
void initState() {
inputPass = [];
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: <Widget>[
const SizedBox(
width: double.maxFinite,
height: double.maxFinite,
child: Image(
image: AssetImage('assets/background.png'),
),
),
CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: true,
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
AuditTheme.primaryColor,
AuditTheme.secondaryColor,
],
),
),
),
leadingWidth: 100,
leading: Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Row(
children: const [
Expanded(
child: ImageIcon(
AssetImage('assets/logo/white_logo.png'),
),
),
Text(
'Audit',
style: TextStyle(fontSize: 20),
),
],
),
),
title: const Text('Sign In'),
centerTitle: true,
actions: [
Transform(
alignment: Alignment.center,
transform: Matrix4.rotationY(math.pi),
child: IconButton(
onPressed: () {},
icon: const Icon(Icons.sort),
),
),
],
),
SliverList(
delegate: SliverChildListDelegate(
[
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Widgets().sixedBoxHeight(50),
Column(
children: [
const CircleAvatar(
radius: 35,
backgroundImage:
AssetImage('assets/logo/audit_logo.png'),
),
Widgets().sixedBoxHeight(10),
const Text(
'Ledjoric Vermont',
style: TextStyle(fontSize: 20),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
pinIconTest(inputPass.isNotEmpty
? Colors.black
: Colors.grey),
pinIconTest(inputPass.length >= 2
? Colors.black
: Colors.grey),
pinIconTest(inputPass.length >= 3
? Colors.black
: Colors.grey),
pinIconTest(inputPass.length == 4
? Colors.black
: Colors.grey),
],
),
Card(
child: Column(
children: [
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
numPad(const Text('1'), () => inputPin('1')),
numPad(const Text('2'), () => inputPin('2')),
numPad(const Text('3'), () => inputPin('3')),
],
),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
numPad(const Text('4'), () => inputPin('4')),
numPad(const Text('5'), () => inputPin('5')),
numPad(const Text('6'), () => inputPin('6')),
],
),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
numPad(const Text('7'), () => inputPin('7')),
numPad(const Text('8'), () => inputPin('8')),
numPad(const Text('9'), () => inputPin('9')),
],
),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: [
const SizedBox(
width: 100,
height: 100,
),
numPad(const Text('0'), () => inputPin('0')),
numPad(
const Icon(Icons.backspace_sharp),
() => deletePin(),
),
],
),
],
),
),
],
),
],
),
),
],
),
],
),
);
}
Widget pinIconTest(Color color) {
return Padding(
padding: const EdgeInsets.all(5.0),
child: Icon(
Icons.circle,
size: 35,
color: color,
),
);
}
Widget numPad(Widget widget, void Function() function) {
return SizedBox(
width: 100,
height: 100,
child: TextButton(
style: TextButton.styleFrom(
foregroundColor: Colors.grey,
textStyle: const TextStyle(
fontSize: 30,
),
),
onPressed: function,
child: widget,
),
);
}
void inputPin(String value) {
setState(() {
inputPass.length != 4 ? inputPass.add(value) : null;
inputPass.length == 4 ? checkPass() : null;
});
print(inputPass);
}
void checkPass() {
var stringList = inputPass.join('');
if (stringList == defaultPass) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const HomeScreen(),
),
);
}
print(stringList);
}
void deletePin() {
setState(() {
inputPass.isNotEmpty ? inputPass.removeLast() : null;
});
print(inputPass);
}
}
I was missing the fact you want to place at the bottom that background, however to achieve that you can do it as the code below shows:
class SignInPage extends StatefulWidget {
const SignInPage({super.key});
#override
State<SignInPage> createState() => _SignInPageState();
}
class _SignInPageState extends State<SignInPage> {
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: <Widget>[
const Align(
alignment: Alignment.bottomCenter,
child: Image(
image: AssetImage('assets/background.png'),
),
),
//Other child here
],
),
);
}
}
And this is the result:
You can use the example below for the status bar. I don't know about the real problem.
You can try using this way for gradient color
SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.light,
statusBarBrightness: Brightness.dark,
statusBarGradient: LinearGradient(
colors: [Colors.red, Colors.blue],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
);
You need to wrap your image in a Positioned Widget.
Positioned(bottom: 0.0,
child: const SizedBox(
width: double.maxFinite,
height: double.maxFinite,
child: Image(
image: AssetImage('assets/background.png'),
),
),
Or you can use the alignment property of the Stack to stick everything onto the bottom. I'm not sure this is exactly what you want though.
body: Stack(
alignment: Alignment.bottomCenter,
fit: StackFit.expand,
children: <Widget>[
const SizedBox(
width: double.maxFinite,
height: double.maxFinite,
child: Image(
image: AssetImage('assets/background.png'),
),
),
I want to hold background image and swipe pageview screen.
However, it seems that I can't swipe if I put image file(I can do only when I delete background image) even though you can see the pageindicator.
](https://i.stack.imgur.com/oXYaL.jpg)
please let me know how to do it. Is there any way to solve it? I don't know what I missed here.
import 'package:eseowakorean/page/secondpage/add_image_profile1.dart';
import 'package:eseowakorean/page/secondpage/add_image_profile2.dart';
import 'package:eseowakorean/page/secondpage/add_image_profile3.dart';
import 'package:eseowakorean/page/secondpage/add_image_profile4.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import '../../widgets/text_widgets.dart';
class AddInformationOnBoarding extends StatefulWidget {
const AddInformationOnBoarding({super.key});
#override
State<AddInformationOnBoarding> createState() =>
_AddInformationOnBoardingState();
}
class _AddInformationOnBoardingState extends State<AddInformationOnBoarding> {
PageController _controller = PageController();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
PageView(
controller: _controller,
children: [
AddImageProfile1(),
AddImageProfile2(),
AddImageProfile3(),
AddImageProfile4(),
],
),
Container(
height: double.infinity,
width: double.infinity,
// alignment: Alignment.center,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/home.jpg',
),
fit: BoxFit.cover),
),
child: Column(
children: [
SizedBox(
height: 60,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 25),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SvgPicture.asset('assets/Skip.svg'),
// poppinsTextWidget('hi')
],
),
),
SizedBox(
height: 60,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
poppinsTextWidget('Let' 's Talk About You!', fontSize: 20)
],
),
],
),
),
Container(
alignment: Alignment(0, 0.75),
child: Row(
children: [
SmoothPageIndicator(controller: _controller, count: 4),
],
mainAxisAlignment: MainAxisAlignment.center,
),
),
],
),
);
}
}
You are containing everything within the same stack. Add the image itself in another Stack widget.
Try this example:
return Scaffold(
backgroundColor: Colors.white,
body: Stack(
alignment: AlignmentDirectional.bottomCenter,
children: <Widget>[
Image.asset(
"assets/home.jpg",
),
Stack(
children: [
PageView(
controller: _controller,
children: [
AddImageProfile1(),
AddImageProfile2(),
AddImageProfile3(),
AddImageProfile4(),
],
),
Column(
children: [
SizedBox(
height: 60,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 25),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SvgPicture.asset('assets/Skip.svg'),
// poppinsTextWidget('hi')
],
),
),
SizedBox(
height: 60,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
poppinsTextWidget('Let' 's Talk About You!', fontSize: 20)
],
),
],
),
Container(
alignment: Alignment(0, 0.75),
child: Row(
children: [
SmoothPageIndicator(controller: _controller, count: 4),
],
mainAxisAlignment: MainAxisAlignment.center,
),
),
],
),
],
),
);
How can fix it?
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Scaffold(
resizeToAvoidBottomInset: false,
body: Stack(
fit: StackFit.loose,
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
flex: 2,
child: buildSearch(),
),
Expanded(
flex: 2,
child: Container(color: Colors.green),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Frequitly Visited'),
TextButton(
onPressed: () {},
child: Text('Show More'),
),
],
),
Expanded(
flex: 6,
child: buildSites(size),
)
],
)
],
),
);
}
buildSearch() {
return Container(
child: FloatingSearchBar(
transitionCurve: Curves.easeInOutCubic,
transition: CircularFloatingSearchBarTransition(),
physics: const BouncingScrollPhysics(),
scrollPadding: EdgeInsets.zero,
builder: (context, _) => _history(),
),
);
}
Container buildSites(size) {
return Container(
color: Colors.black,
width: size.width,
);
}
Widget _history() {
List<String> listHistory = [
'Flutter',
'Python',
'Nodejs',
'Rails',
];
return ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Material(
child: Column(
children: listHistory
.map((e) => ListTile(
title: Text(e),
onTap: () {},
))
.toList(),
),
),
);
}
}
try to fixed the height of search & container, expanded only flexible part:
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
height: 100,
child: buildSearch(),
),
Container(
height: 100,
child: Container(color: Colors.green),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Frequitly Visited'),
TextButton(
onPressed: () {},
child: Text('Show More'),
),
],
),
Expanded(
child: buildSites(size),
)
],
)
You can just remove the Expanded widget wrapped around your buildSearch() widget and give a desired padding or you can also your sizedbox with a desiredHeight below and above the buildSearch()
so basically change
...
Expanded(
flex: 2,
child: buildSearch(),
),
...
to
...
Padding(
padding:EdgeInsets.only(top:20,bottom:50), // adding a suitable padding should fix it
child:buildSearch(),
)
...
I have the following table
#override
Widget build(BuildContext context){
final TheGroupPageArguments arguments = ModalRoute.of(context).settings.arguments;
return Scaffold(
body: Padding(
padding: EdgeInsets.all(20.0),
child: Column(
children: [
Flexible(
flex: 1,
child: Align(
alignment: Alignment.center,
child: DigitalSpeedMeter(),
),
),
Flexible(
flex: 6,
child: Table(
children: [
TableRow(children: [backButton(), backButton(), backButton()]),
TableRow(children: [backButton(), backButton(), backButton()]),
],
),
),
]
),
),
);
}
But it only takes half the screen height. How can I make it strecht to it's parent's height?
This is how it looks now
This is what it should look like
This is what it should look like
You can use the "Expanded" instead of "Flexible".
I can't find a good solution.
Anyone know a good way?
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(20.0),
child: Column(
children: [
Expanded(
flex: 1,
child: Container(
color: Colors.yellow,
child: Align(
alignment: Alignment.center,
child: Text(
'0\nMPH',
textAlign: TextAlign.center,
),
),
),
),
Expanded(
flex: 6,
child: Column(
children: [
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: FlatButton(
onPressed: () {},
color: Colors.tealAccent,
child: Text("button1"),
),
),
Expanded(
child: FlatButton(
onPressed: () {},
color: Colors.green,
child: Text("button2"),
),
),
],
),
),
Expanded(
child: Container(
color: Colors.grey,
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: FlatButton(
onPressed: () {},
color: Colors.blue,
child: Text("button3"),
),
),
Expanded(
child: FlatButton(
onPressed: () {},
color: Colors.amber,
child: Text("button4"),
),
),
],
),
),
),
],
),
),
],
),
),
);
}
I found a solution. How about this?
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(20.0),
child: Column(children: [
Flexible(
flex: 1,
child: Align(
alignment: Alignment.center,
child: Container(
color: Colors.yellow,
child: Align(
alignment: Alignment.center,
child: Text(
'0\nMPH',
textAlign: TextAlign.center,
),
),
),
),
),
Flexible(
flex: 6,
child: Table(
children: [
TableRow(children: [backButton(), backButton(), backButton()]),
TableRow(children: [backButton(), backButton(), backButton()]),
],
),
),
]),
),
);
}
Widget backButton() {
return Container(
height: MediaQuery.of(context).size.height / 7 * 6 / 2 - 7,
child: FlatButton(
onPressed: () {},
color: Colors.tealAccent,
child: Text("button"),
),
);
}
I ended up doing the following. A widget that makes the rows and columns dynamically based on the the widgets put into it.
import 'package:flutter/material.dart';
class ExpandingGrid extends StatelessWidget {
final List<Widget> tiles;
final int columns;
const ExpandingGrid({this.tiles, this.columns});
int _rows(){
return (tiles.length / columns).ceil();
}
int _tileIndex(int row, int column) => row * columns + column;
Widget _gridTile(int row, int column){
if(_tileIndex(row, column) < tiles.length)
{
return Expanded(
child: tiles[_tileIndex(row, column)],
);
}
return Spacer();
}
#override
Widget build(BuildContext context) {
return Column(
children:
[
for(int r = 0; r < _rows(); r++ )
Expanded(
child: Row
(
children :
[
for(int c = 0; c < columns; c++)
_gridTile(r, c),
]
),
)
]
);
}
}
i am trying to add item in list when i click on add button, all code is ok, but i am getting error invalid reference to this expression. i am using stateful widget.
List<Widget> _listSection = [];
body: Container(
child: Stack(
children: [
FloatingActionButton(
onPressed: () {
_listSection.add(
listSectionMethod(
"title three", "hello from click", Icons.forward),
);
setState(() {});
},
),
],
),
),
),
);
}
}
Widget listSection = Container(
margin: EdgeInsets.only(top: 210),
child: ListView(
children: [
Column(
children: [
Column(
children: this._listSection, // ----> ERROR HERE
),
],
),
],
),
);
List Section Method:
Card listSectionMethod(String title, String subtitle, IconData icon) {
return new Card(
child: ListTile(
title: Text(
title,
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text(subtitle),
trailing: Icon(
icon,
color: Colors.blue,
),
),
);
}
change this:
Widget listSection = Container(
margin: EdgeInsets.only(top: 210),
child: ListView(
children: [
Column(
children: [
Column(
children: this._listSection,
),
],
),
],
),
);
for this:
Widget listSection() {
return Container(
margin: EdgeInsets.only(top: 210),
child: ListView(
children: [
Column(
children: this._listSection,
),
],
),
);
}