Flutter: Prevent some children from getting stretched - flutter

Do you have an idea on how to prevent child from getting stretched.
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(child: ...),
Row( // idon't want this child to be stretched
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
FlatButton(
child: Icon(Icons.add),
onPressed: () {},
color: Color(0xFFE2EDE4),
),
Text(
'$quantity',
style: Theme.of(context).textTheme.headline5.copyWith(
fontWeight: FontWeight.bold,
),
),
FlatButton(
child: Icon(Icons.remove),
onPressed: () {},
color: Color(0xFFE2EDE4),
),
],
),
],
);
I tried to wrap it in ConstrainedBox but still it is being stretched.

In this case, the crossAxisAlignment: CrossAxisAlignment.stretch property of Column don't affect to Row child. Instead of using mainAxisAlignment: MainAxisAlignment.spaceBetween
You can add SizedBox(width: ...)

If you want stretch Row widget, how about remove 'mainAxisAlignment' of Row.
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(height: 200, color: Colors.blue, child: Text('123'),),
Column(
children: <Widget> [
Row( // idon't want this child to be stretched
children: [
FlatButton(
child: Icon(Icons.add),
onPressed: () {},
color: Color(0xFFE2EDE4),
),
Text(
'qweqe',
style: Theme.of(context).textTheme.headline5.copyWith(
fontWeight: FontWeight.bold,
),
),
FlatButton(
child: Icon(Icons.remove),
onPressed: () {},
color: Color(0xFFE2EDE4),
),
],
),
]),
],
);
}
}

Related

ChoiceChip not expanding with IntrinsicWidth

I'm wondering why ChoiceChip is not expanding like ElevatedButton does.
Here is an example: (look at dartpad)
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: MyWidget(),
),
);
}
}
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(children: [
IntrinsicWidth(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: ElevatedButton(
child: const Text('Larger Text'),
onPressed: () {},
)),
Expanded(
child: ElevatedButton(
child: const Text('Text'),
onPressed: () {},
)),
],
)),
IntrinsicWidth(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: const [
Expanded(
child: ChoiceChip(
label: Text('Larger Text'),
selected: false,
)),
Expanded(
child: ChoiceChip(
label: Text('Text'),
selected: false,
)),
],
))
]);
}
}
To solve this, let's start by enabling Flutter Inspector, we can see the second IntrinsicWidth width and its children don't fill their parent as the first one (two problems)
Solve 1st problem: IntrinsicWidth children don't fill their parent width
So, the problem is the size of the 2nd IntrinsicWidth's children is not wide/big enough so that it can be full of parent width. Try increasing its width manually by wrapping it in a Container with double.infinity width, like this:
ChoiceChip(
label: Container(width: double.infinity, child: Text('Larger Text')),
selected: false,
)
New result:
Solve 2nd problem: the 2nd IntrinsicWidth don't fill their parent width
Let's leave Column children can have the maximum width as it is (removing all IntrinsicWidth inside its children) and then wrap the Column by an IntrinsicWidth. Complete sample code:
Sample code
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: MyWidget(),
),
);
}
}
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
#override
Widget build(BuildContext context) {
return IntrinsicWidth(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: ElevatedButton(
child: const Text('Larger Text'),
onPressed: () {},
),
),
Expanded(
child: ElevatedButton(
child: const Text('Text'),
onPressed: () {},
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: ChoiceChip(
label: Container(width: double.infinity, child: Text('Larger Text')),
selected: false,
),
),
Expanded(
child: ChoiceChip(
label: Container(width: double.infinity, child: Text('Text')),
selected: false,
),
),
],
),
],
),
);
}
}
Final result:
Because under the hood the widgets are designed differently (that's why the names).
I haven't checked the code in detail (you can do that by ctrl + click on Widget Name).
But best guess, visual density is lower in chips for being compact and higher in buttons.
More on technical difference to understand which to use : chips-vs-button

Scroll single ListTile in ListView

Scroll single ListTile in ListView
class MainScreen extends MvcScreen<MainScreenController> {
#override
MainScreenController initController() => MainScreenController();
#override
Widget defaultScreenLayout(
ScreenParameters screenParameters, MainScreenController controller) {
return _tabsLayout;
}
Widget get _tabsLayout => DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Text(AppScaffold().title),
actions: <Widget>[
IconButton(icon: Icon(Icons.search), onPressed: () {}),
],
),
drawer: TelegramDrawer(),
floatingActionButton: FloatingActionButton(
backgroundColor: Color(0xff65a9e0),
child: Icon(Icons.create),
onPressed: () {},
),
body: _body,
),
);
Widget get _body => Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(child: _chatsListView),
],
).paddingAll(0);
Widget get _chatsListView => Container(
child:
ListView.builder(itemCount: 1, itemBuilder: channelListItemBuilder),
);
Widget channelListItemBuilder(context, int index) {
return ListTile(
leading: CircleAvatar(
backgroundColor: Colors.blueGrey[200],
foregroundColor: Colors.white,
radius: 28,
child: Icon(
Icons.archive,
size: 30,
),
),
title: Text(
"Archived Chats",
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w500),
),
);
}
Once you wrap ListView in the column it does not allow you to scroll view. Therefore here I've changed the code:
Widget get _body => Expanded(child:Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(child: _chatsListView),
],
).paddingAll(0));

How can I resolve child duplication error?

How to resolve child duplication error:
Error: Duplicated named argument 'child'.
child: CenteredView(
This is my code:
Container(
child: RaisedButton(
onPressed: (){},
child: Text(
'Alcoholic Beverages',
style: TextStyle(
decoration:TextDecoration.underline,
fontSize: 25,
),
),
),
child: CenteredView(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
NavigationBar()
]
)
)
),
]
),
);
}
}
In your Container you have two child, when Container widget can take only a single child. So you need to use some widget that can have more than one child. Column and Row allows you to do that.
Check this link to read more about multi-child widget, unlike Container, which is single-child widget, Column and Row are Multi-child widget.
Multi-Child Widget
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
class selClass extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: sel(),
);
}
}
class sel extends StatefulWidget {
#override
_selState createState() => _selState();
}
class _selState extends State<sel> {
String _date = "Not set";
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(child:SingleChildScrollView(
child: Container( child: Column (
children: [
RaisedButton(
onPressed: (){},
child: Text(
'Alcoholic Beverages',
style: TextStyle(
decoration:TextDecoration.underline,
fontSize: 25,
),
),
),
CenteredView(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
NavigationBar()
]
),
),
]
),
);
}
}
Container can have only One Child . That's why you're getting this error. You need to Column if your view is vertical or Row if your view is horizontal. Use this to solve your problem:
Column :
Container(
child: Column(
children: [
RaisedButton(
onPressed: () {},
child: Text(
'Alcoholic Beverages',
style: TextStyle(
decoration: TextDecoration.underline,
fontSize: 25,
),
),
),
CenteredView(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[NavigationBar()])),
],
),
),
);
}
}
OR
Row :
Container(
child: Row(
children: [
RaisedButton(
onPressed: () {},
child: Text(
'Alcoholic Beverages',
style: TextStyle(
decoration: TextDecoration.underline,
fontSize: 25,
),
),
),
CenteredView(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[NavigationBar()])),
],
),
),
);
}
}
Container widget can only have one child.
To lay out multiple children, let this widget's child be a widget such as Row, Column, or Stack.

Align text in centre of screen

I am trying to use Expand widget in Column so user can tap in any position of screen to increase counter, but there is an issue in alignment of text in crossAxisAlignment and mainAxisAlignment of the column it didn't apply on Expand widget as the following
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black12,
body: SafeArea(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: GestureDetector(
onTap: () {
setState(() {
i++;
print(i);
});
},
child: Text(
i.toString(),
style: TextStyle(fontSize: 50.0, color: Colors.blueAccent),
textAlign: TextAlign.center,
),
),
),
],
),
),
),
),
);
You went with the wrong approach because you can't Center an Expanded because Expanded takes the entire available space inside Row or Column in your case Column with single Widget inside children the GestureDetector. Here is one of a solution for what you want to achieve
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black12,
body: SafeArea(
child: Center(
child: Stack(
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: GestureDetector(
onTap: () {
setState(() => i++;);
},
),
),
],
),
Align(
alignment: Alignment.center,
child: Text(
'$i',
style: TextStyle(fontSize: 50.0, color: Colors.blueAccent),
),
),
],
),
),
),
);
}
another solution using FlatButton inside SizedBox.expand()
so you don't need to fight with a single child column.
class _MyAppState extends State<MyApp> {
int i = 0;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black12,
body: SafeArea(
child: SizedBox.expand(
child: FlatButton(
onPressed: () {
setState(() {
i++;
print(i);
});
},
child: Text(
i.toString(),
style: TextStyle(fontSize: 50.0, color: Colors.blueAccent),
),
),
),
),
),
);
}
}

Flutter, how to get rid of raisedButton bottom margin?

So I'm trying to remove the bottom margin of raisedButton so it will look like it is merged with the card below it.
here's what it looks like
here is my code
Expanded(
child: Card(
elevation: 5,
// shape:
// RoundedRectangleBorder(borderRadius: BorderRadius.circular(22)),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Apakah anak sudah bisa ... ?",
style: TextStyle(fontWeight: FontWeight.bold)),
),
],
),
Row(
children: <Widget>[
Expanded(
child: RaisedButton(
child: Text(
"Iya",
style: TextStyle(color: Colors.white),
),
color: Colors.green[300],
onPressed: () {}),
),
Expanded(
child: RaisedButton(
child: Text(
"Tidak",
style: TextStyle(color: Colors.white),
),
color: Colors.red[200],
onPressed: () {}))
],
)
],
),
),
)
or do you guys have any other alternative solution to achieve that?
You can explicitly set your Row height to match the height of your RaisedButton. Simply wrap it inside a Container and add the height attribute.
If you want to, you can access the default height by using Theme.of(context).buttonTheme.height. Theme.of returns the ThemeData used in the current context.
Here a minimal example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Container(
child: Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Test'),
Container(
height: Theme.of(context).buttonTheme.height,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
RaisedButton(
onPressed: () {},
child: Text('Yes'),
color: Colors.green,
),
RaisedButton(
onPressed: (){},
child: Text('No'),
color: Colors.red,
)
],
),
),
],
)
),
),
)),
);
}
}
I had the same problem. NikasPor's answer didnt work for me, unfortunately. The way I fixed it is by seeting the crossAxisAlignment on the row to .stretch
Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children:[ /* Buttons Here */]
)