Flutter reduce space between widgets - flutter

I try to display a ExpansionTile with some text in it followed by an Image. Referring to the screenshot you can see that there is some space between both widgets. Does someone know how I can reduce this space?
class Test extends StatelessWidget {
const Test({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: backGround,
appBar: AppBar(
title: const Text('Aromatics'),
backgroundColor: appbarColor,
),
body: Column(
children: [
ExpansionTile(
iconColor: titleColor,
title: const Text('Tst', style: TextStyle(color: titleColor)),
subtitle: const Text('Test subtitle',
style: TextStyle(color: Colors.white)),
children: [
Container(
margin: const EdgeInsets.only(left: 20),
child: Column(
children: const [
Text('Test text',
style:
TextStyle(color: Colors.white, fontSize: 13)),
],
),
),
]),
const SizedBox(
height: 1,
),
Expanded(
child: Image.asset('assets/images/test.webp'),
),
],
));
}
}

As per the ExpansionTile Doc, you can use childrenPadding to manage the padding for the children widget
Specifies padding for children.
If this property is null then ExpansionTileThemeData.childrenPadding is used. If that is also null then the value of childrenPadding is EdgeInsets.zero.

Won't removing Expanded suit your goals?
...
const SizedBox(
height: 1,
),
Image.asset('assets/images/test.webp'),
...

Just remove the Expanded widget around the image because it is taking all the remaning space in the Column for the image.
Current Code:
Column(
children: [
...
Expanded(
child: Image.asset('assets/images/test.webp'),
),
...
],
),
New Code:
Column(
children: [
...
Image.asset('assets/images/test.webp'),
...
],
),```

Related

ElevatedButton Position Changing method

I have an Elevated Button which is on of the bottom of the Page and I am a beginner sorry for this silly doubts but i can't figure out how to change the position of the button I dont know how to try positioned widget too. Kindly help me
I tried positioned widget but couldn't do well can anyone help me with this. here is my full code.
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: MyApp(),
));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
child: PageView.builder(
itemBuilder: (context, index)=> const OnBoardContent(
image: 'assets/splash-1.png',
description: "All under one roof with different approach"),
),
),
SizedBox(
height: 30,
width: 200,
child: ElevatedButton(
onPressed: (){},
child: const Text("Tap to get started"),
),
),
],
)
),
);
}
}
class OnBoardContent extends StatelessWidget {
const OnBoardContent({
Key? key,
required this.image,
required this.description,
}) : super(key: key);
final String image, description;
#override
Widget build(BuildContext context) {
return Column(
children: [
const SizedBox(
height: 160,
),
const Text("Naz-Kearn",
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold
)),
const Text("A simplify learning App",
style: TextStyle(
fontWeight: FontWeight.normal
),
),
Image.asset(image),
const SizedBox(
height: 50,
),
Text(description,
textAlign: TextAlign.center,
style: const TextStyle(fontWeight: FontWeight.normal),
),
],
);
}
}
Output of the above code
You need your widgets in a stack if you want to use Positioned widget on them :
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: MyApp(),
));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack( //wrapped the whole column with a stack so that all the other widgets doesn't get disturbed
children: [
Column(
children: [
Expanded(
child: PageView.builder(
itemBuilder: (context, index)=> const OnBoardContent(
image: 'assets/splash-1.png',
description: "All under one roof with different approach"),
),
),
],
),
Positioned(
top: MediaQuery.of(context).size.height*0.7, //change the 0.7 part to any number you like
child: SizedBox(
height: 30,
width: 200,
child: ElevatedButton(
onPressed: (){},
child: const Text("Tap to get started"),
),
),
),
],
)
),
);
}
}
class OnBoardContent extends StatelessWidget {
const OnBoardContent({
Key? key,
required this.image,
required this.description,
}) : super(key: key);
final String image, description;
#override
Widget build(BuildContext context) {
return Column(
children: [
const SizedBox(
height: 160,
),
const Text("Naz-Kearn",
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold
)),
const Text("A simplify learning App",
style: TextStyle(
fontWeight: FontWeight.normal
),
),
Image.asset(image),
const SizedBox(
height: 50,
),
Text(description,
textAlign: TextAlign.center,
style: const TextStyle(fontWeight: FontWeight.normal),
),
],
);
}
}
try this code, you can use alignment property of the Stack widget to center everything.
SafeArea(
child: Stack(
alignment: Alignment.center, //do this
children: [
You can wrap your button with Padding widget which helps you to add padding as you like
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
child: PageView.builder(
itemBuilder: (context, index)=> const OnBoardContent(
image: 'assets/splash-1.png',
description: "All under one roof with different approach"),
),
),
Padding(
padding: EdgeInsets.all(8),
child: SizedBox(
height: 30,
width: 200,
child: ElevatedButton(
onPressed: (){},
child: const Text("Tap to get started"),
),
),),
],
)
),
);
}
Firstly please mention what precisely the issue you are facing. If you have a problem with the get started button, what is the expected place for the get started button in the design?
Based on the code given, I'm hoping that the get started button should be at the bottom of the screen with some space below. You have already placed the button at the bottom, but you are not able to give space below.
There are some possible ways, you can use it with the get started button component.
Instead of this,
SizedBox(
height: 30,
width: 200,
child: ElevatedButton(
onPressed: (){},
child: const Text("Tap to get started"),
),
),
Option 1
Use container with margin
Container(
height: 30,
width: 200,
margin: EdgeInsets.only(
bottom: 50,
),
child: ElevatedButton(
onPressed: () {},
child: const Text("Tap to get started"),
),
),
Option 2
Wrap existing SizedBox with padding widget
Padding(
padding: EdgeInsets.only(bottom: 50.0),
child: Sizedbox(
height: 30,
width: 200,
child: ElevatedButton(
onPressed: () {},
child: const Text("Tap to get started"),
),
),
),
Even with some more ways to move the button wherever you need, you can try your own with the following widgets Expanded(), Spacer(), SizedBox(), Positioned() and etc.

How to align the child of a column on the bottom while keeping other children's position at the center in Flutter?

I want to align the text "2022" on the bottom of the screen while keeping the image and its neighbor text at the center of the screen.
class SplashScreen extends StatelessWidget {
const SplashScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Globalcolors.mainColor,
body: Container(
padding: const EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Image.asset(
'assets/images/splash_logo.png',
color: Colors.white,
),
),
const Padding(
padding: EdgeInsets.all(50),
child: Text(
'Sample Text',
style: TextStyle(
color: Colors.white,
fontSize: 36,
fontFamily: 'MouseMemoirs'),
),
),
const Text(
'2022',
style: TextStyle(color: Colors.white, fontSize: 12),
),
],
),
),
);
}
}
I tried to use this link to solve the problem. I used Expanded:
const Expanded(
child: Align(
alignment: FractionalOffset.bottomCenter,
child: Text(
'2022',
style: TextStyle(color: Colors.white, fontSize: 12),
),
),
)
But, The result is not good:
You can user Stack and column widgets like
Stack(
children: [
Column(), // contains the image and title
Align(
alignment: Alignment.bottomCenter,
child: Text("2022"),
),
]
)
You can also use Positioned widget to align the text 2022
you can use the bottom method that comes with the scaffold
Scaffold(
bottom : Text("2020")
)
this will make the text always on the bottom of the screen

How to add an icon after text widget in an expanded widget?

I want the arrow_right icon close after the Text Widget, but I have to wrap the text with a Expanded as it might overflow
I think this can solve it.
Row(
children: const [
Expanded(
child: Text(
'this line is overflow, but icon is in right position',
style: TextStyle(fontSize: 12),
softWrap: false,
maxLines: 2,
overflow: TextOverflow.ellipsis, // new
),
),
],
)
or
Row(
children: const [
Expanded(
child: FittedBox(
child: Text(
'this line is overflow, but icon is in right position',
style: TextStyle(fontSize: 12),
softWrap: false,
overflow: TextOverflow.ellipsis,
),
),
),
],
)
code Example
return Scaffold(
body: SafeArea(
child: Expanded(
child: ColoredBox(
color: Colors.deepOrangeAccent,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Text(
'Line 1',
style: TextStyle(fontSize: 24),
),
Row(
children: const [
Container(
child: Text(
'this line might overflow',
style: TextStyle(fontSize: 12),
),
),
Icon(Icons.arrow_right),
],
),
Row(
children: const [
Expanded(
child: Text(
'this line is overflow, but icon is in right position // this line is overflow, but icon is in right position',
style: TextStyle(fontSize: 12),
softWrap: false,
//maxLines: 2,
overflow: TextOverflow.ellipsis, // new
),
),
Icon(Icons.arrow_right),
],
),
],
),
),
),
),
);
result Image
I'll tell you two ways I know of.
Use Container Widget
How to fix the size by giving width: This method allows you to attach an icon next to the text.
Use Expanded Widget
'Expanded' is a percentage. Since you are using one Expanded widget now, the Text widget is taking up all the remaining space except for the space for the Icon widget.
You can use it according to the conditions of your app.
finally, Flexible can do it!!!
You should try this solution
main.dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
SizedBox(
height: 130,
child: Row(
children: [
Expanded(
flex: 2,
child: Container(
color: Colors.yellowAccent,
),
),
Expanded(
flex: 5,
child: Column(
children: [
Expanded(
flex: 5,
child: Container(
color: Colors.deepOrangeAccent,
width: MediaQuery.of(context).size.width,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Expanded(
flex: 2,
child: FittedBox(
child: Text("line 1"),
),
),
Expanded(
flex: 3,
child: Column(
children: [
Expanded(
child: Row(
children: const [
Expanded(
child: Text(
"this line might overflow",
overflow: TextOverflow.ellipsis,
),
),
AspectRatio(
aspectRatio: 1,
child: FittedBox(
child: Icon(Icons.arrow_right)),
),
],
)),
Expanded(
child: Row(
children: const [
Expanded(
child: Text(
"this line is overflow, the icon is in right position",
overflow: TextOverflow.ellipsis,
),
),
AspectRatio(
aspectRatio: 1,
child: FittedBox(
child: Icon(Icons.arrow_right)),
),
],
)),
],
),
),
],
),
),
),
Expanded(
flex: 3,
child: Container(
color: Colors.deepPurpleAccent,
),
),
],
),
),
],
),
),
],
),
);
}
}
Solution Image
N.B: This Solution is totally responsive.
******* TRY THIS ********
Text("Any Text Add",
textScaleFactor: 0.85,
style: TextStyle(
fontSize: 12
),
)

Flutter Bottom overflowed by xx pixel

I am trying to construct a page with multiple widgets Row, Column, Expanded, ListView, etc...
I am a bit confused. I want a page scrollable with my widgets ThemeList.
I have the error :
A RenderFlex overflowed by 28 pixels on the bottom.
class SettingsViewState extends State<SettingsView> {
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
drawer: const NavDrawer(),
appBar: AppBar(
title: Text(AppLocalizations.of(context)!.settingsTitle),
backgroundColor: Theme.of(context).primaryColor,
),
body: CustomScrollView(slivers: [
SliverFillRemaining(
child: Column(
children: const [
ThemeList(),
SizedBox(height: 8),
ThemeList(),
SizedBox(height: 8),
ThemeList(),
],
),
),
]),
);
}
}
class ThemeList extends StatelessWidget {
const ThemeList({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Expanded(
child: Padding(
padding: const EdgeInsets.all(10),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Theme.of(context).primaryColor, width: 2),
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 5, left: 20),
child: Text(
AppLocalizations.of(context)!.settingsThemeSubTitle,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 23,
),
),
)
],
),
ListView.builder(
shrinkWrap: true,
padding: const EdgeInsets.all(8),
itemCount: AppTheme.values.length,
itemBuilder: (context, index) {
final itemAppTheme = AppTheme.values[index];
var nameTheme = itemAppTheme.toString()
return Card(
color: appThemeData[itemAppTheme]?.primaryColor,
child: ListTile(
title: Text(
nameTheme,
style: appThemeData[itemAppTheme]?.textTheme.bodyText1,
),
onTap: () {
BlocProvider.of<ThemeBloc>(context).add(
ThemeChanged(theme: itemAppTheme),
);
Preferences.saveTheme(itemAppTheme);
},
),
);
},
)
],
),
),
),
);
}
}
Desired result :
Just wrap the ListView.builder() inside ThemeList with an Expanded and the problem would vanish.
If you want to have all the items inside each ThemeList displayed with a scroll for the whole screen then the easiest why is to do the following:
Change the CustomScrollView in the body of the Scaffold to be SingleChildScrollView with the Column as its child.
Remove the Expanded at the start of ThemeList.
Remove the ListView.builder() inside the ThemeList and replace it with any looping logic to directly render the cards, for example:
...AppTheme.values.map((itemAppTheme) {
var nameTheme = itemAppTheme.toString();
return Card(
color: appThemeData[itemAppTheme]?.primaryColor,
child: ListTile(
title: Text(
nameTheme,
style: appThemeData[itemAppTheme]?.textTheme.bodyText1,
),
onTap: () {
BlocProvider.of<ThemeBloc>(context).add(
ThemeChanged(theme: itemAppTheme),
);
Preferences.saveTheme(itemAppTheme);
},
),
);
}).toList()

How to add divider & Subtitle in drawer in flutter

I would like to add Subtitle and divider in navigation drawer like below image screen shot.
I have written below code for navigation drawer but not able to find where i can put Subtitle & divider.
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: const <Widget>[
DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text(
'Drawer Header',
style: TextStyle(
color: Colors.white,
fontSize: 24,
),
),
),
ListTile(
leading: Icon(Icons.message),
title: Text('Messages'),
),
ListTile(
leading: Icon(Icons.account_circle),
title: Text('Profile'),
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Settings'),
),
],
),
),
there is a widget for it called Divider
you could simply add a Divider as one of the childrens of the ListView
for the subtitle you could add a Text widget and style it to look how you need it to look using a TextStyle
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: const <Widget>[
DrawerHeader(...),
Divider(), //here is a divider
Text("subtitle", style: TextStyle(...)),
ListTile(...),
ListTile(...),
Divider(), //here is a divider
ListTile(...),
//rest of your items
],
),
),
You can do it with Divider wigdet https://api.flutter.dev/flutter/material/Divider-class.html
Just Provide a Divider() within every ListTile where you wanna put that thin line on.
I had the same problem and solved it as follows:
class DividerWithSubheader extends StatelessWidget {
const DividerWithSubheader({Key? key, required this.subHeader,}) : super(key: key);
final String subHeader;
#override
Widget build(BuildContext context) {
return Stack(
children: [
Divider(),
Container(
padding: const EdgeInsets.only(left: 20),
child: Align(
alignment: AlignmentDirectional.centerStart,
child: Text(
subHeader,
style: Theme.of(context).textTheme.caption,
textAlign: TextAlign.start,
),
),
),
],
);
}}
And use it like this:
ListView(children: <Widget>[
DividerWithSubheader(subHeader: 'subheader Test'),
]),