ChoiceChip not expanding with IntrinsicWidth - flutter

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

Related

How to make this in Flutter i am new in flutter so if anyone knows

I want one row with this one big image on left and two images on right with one up and the second down.
thanks in advance if Someone can help!!
The key insight is to break the layout into nested rows and/or columns. Check out this example,
import 'package:flutter/material.dart';
void main() {
runApp(App());
}
class App extends StatefulWidget {
#override
_AppState createState() => _AppState();
}
class _AppState extends State<App> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.white,
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: getContainer(Colors.green),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: getContainer(Colors.yellow),
),
Expanded(
child: getContainer(Colors.red),
)
],
),
),
],
),
),
);
}
}
Widget getContainer(MaterialColor color) =>
Container(height: 50, width: 50, color: color);
Everything is contained in one row, the first column will be larger than the second one with the widget Expanded flex :1. In the second column, there's a column widget with that you'll have two rows for your image.
import 'package:flutter/material.dart';
class Home extends StatelessWidget {
const Home({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Row(
children: [
Expanded(
child: SizedBox(
child: Image.asset('your large image'),
),
flex: 1,
),
Expanded(
child: Column(
children: [
Image.asset('your second image'),
Image.asset('your third image'),
],
),
flex: 0,
)
],
),
),
);
}
}
solved
**here is the example **
import 'package:flutter/material.dart';
class BagScreen extends StatelessWidget {
const BagScreen({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
// color: Colors.red,
height: 400,
width: 400,
child: Row(
children: [
Container(
child: Image.asset(
"assets/images/bgimage.PNG",
fit: BoxFit.contain,
width: 250.0,
// height: 350.0,
),
),
SizedBox(
width: 10.0,
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(
height: 10.0,
),
Container(
child: Image.asset("assets/images/upsm.PNG"),
),
Container(
child: Image.asset("assets/images/upsm.PNG"),
),
],
)
],
),
),
),
);
}
}

How to configure a container in flutter to use the same height of an other children in the same row or column

I like to increase the height of the widget "B" so the orange color use the same space like the green color. I have added a code example.
If a added Extended() like Expanded(Container(Text('B'))) the full horizontal space of the screen is used.
If a added Extended() like Column(Expanded(Container(Text('B')))) the full vertical space of the screen is used.
Does someone has a hint?
Thank you in advance!
Gretings
Michael
Problem:
Goal:
Code:
import 'package:flutter/material.dart';
void main() {
runApp(DemoX());
}
class DemoX extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
color: Colors.red,
child: Container(
color: Colors.green,
child: Text('A1\nA2'),
),
),
Container(
color: Colors.orange,
child: Text('B'),
),
],
),
),
),
);
}
}
Screenshot
Code:
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: IntrinsicHeight(
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
color: Colors.green,
child: Text('A1\nA2'),
),
Container(
color: Colors.orange,
child: Text('B'),
),
],
),
),
),
);
}

Pull down in a flutter app to refresh the app state

I want to update/refresh the balanceAvailable value inside the Text Widget by pulling down the mobile screen in a flutter app.
I have attached a sample code that I am working on for your reference.
I does not seem to work as intended. I would be grateful if someone can provide a solution to this issue.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
GlobalKey<RefreshIndicatorState>();
double balanceAvailable = 0.0;
Future<void> _onRefreshing() async {
setState(() async {
balanceAvailable = 100;
print('newbalance : $balanceAvailable');
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: _onRefreshing,
child: Container(
width: double.infinity,
color: Colors.lightBlue,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
onPressed: () async {},
child: Text("Just a Button 1"),
),
SizedBox(
height: 100,
),
Text('$balanceAvailable'),
],
),
)),
),
);
}
}
In order for RefreshIndicator to work, it needs a vertically scrollable descendant like a ListView:
RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: _onRefreshing,
child: ListView(
physics: const AlwaysScrollableScrollPhysics(),
children: [
Container(
width: double.infinity,
color: Colors.lightBlue,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
onPressed: () async {},
child: Text("Just a Button 1"),
),
SizedBox(
height: 100,
),
Text('$balanceAvailable'),
],
),
),
],
),
)

How to make row/column of non-fixed sized parent fill the whole space

I am trying to do it with Expanded but I am getting 'RenderFlex children have non-zero flex but incoming width constraints are unbounded.' which is expected because the size of parent is not defined.
Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text(
'something',
style: Theme.of(context).primaryTextTheme.headline2,
),
Expanded(
child: Container(),
),
]
)
If your Row is wrapped within an Column widget it will take up all of the available space and give your Row the required Parent width. This will be rendered at the top of the Column.
import 'package:flutter/material.dart';
class TestScreen extends StatelessWidget {
static const routeName = '/testScreen';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test'),
),
body: Column(
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text(
'something',
style: Theme.of(context).primaryTextTheme.headline2,
),
Expanded(
child: Container(),
),
],
),
],
),
);
}
}
If you want the widget to take up entire height as well then wrap it again with an Expanded
import 'package:flutter/material.dart';
class TestScreen extends StatelessWidget {
static const routeName = '/testScreen';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test'),
),
body: Column(
children: <Widget>[
Expanded(
child: Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text(
'something',
style: Theme.of(context).primaryTextTheme.headline2,
),
Expanded(
child: Container(),
),
],
),
),
],
),
);
}
}
If you do not give the Row this fixed area it will expand indefinitely off the side of your screen
Non Column solution
body: SingleChildScrollView(
child: Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text(
'something',
style: Theme.of(context).primaryTextTheme.headline2,
),
Expanded(
child: Container(),
),
],
),
),

Can't find correct layout option for how to use ListView in a custom Widget

I am trying to extract re-use a simple widget that is then referenced in parent widget. The custom widget simply uses a row to layout a textField and a button, and below this I Want to have a listview showing items. I then embed in the customwidget in parent, but it continually throws Error. I have not figured out how to get the custom widget working where I can use ListView or column layout inside. Below is the 2 simplified widgets that demo the issue.
Here is the parent widget, which is where I call the custom widget PlayListControl()
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My Playlists'),
),
body: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.ltr,
children: <Widget>[
Container(
alignment: Alignment.center,
margin: EdgeInsets.all(20),
child: Text('Test'),
),
PlayListControl(),
],
),
),
drawer: SideDrawer(),
);
}
}
And here is the playlistcontrol widget.
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(10),
child: Column(
children: <Widget>[
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 200,
child: TextField(),
),
ButtonTheme(
minWidth: 30,
child: RaisedButton(
textColor: Colors.white,
child: Text('add'),
onPressed: () {},
)),
],
),
),
Expanded(
child: ListView(
children: <Widget>[
Text('Widget 1'),
Text('Widget 2'),
],
),
)
],
),
);
}
}
No matter what I try, it always complains about layout issue related to height. I would have thought wrapping the ListView in Expanded would solve the issue, but it doesn't. Only if I use a container and specify height do I not get the errors, but I want to use whatever available space there is.
How can I get this playlistcontrol() widget to properly render inside a parent control?
you forgot to wrap the first container of PlayListControl in Expanded widget..
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text('My Playlists'),
),
body: Container(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.ltr,
children: <Widget>[
Container(
alignment: Alignment.center,
margin: EdgeInsets.all(20),
child: Text('Test'),
),
PlayListControl(),
],
),
),
));
}
}
class PlayListControl extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Expanded(
child: Container(
margin: EdgeInsets.all(10),
child: Column(
children: <Widget>[
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 200,
child: TextField(),
),
ButtonTheme(
minWidth: 30,
child: RaisedButton(
textColor: Colors.white,
child: Text('add'),
onPressed: () {},
)),
],
),
),
Expanded(
child: ListView(
children: <Widget>[
Text('Widget 1'),
Text('Widget 2'),
],
),
)
],
),
),
);
}
}