Flutter: How to Auto-Fit Text Inside (Expanded) Floating Action Button? - flutter

Let's say in Flutter you have:
return Row(
children: [
Expanded(
child: FloatingActionButton(
onPressed: () {},
child: Text(myObject.unknownUntilRunTimeText),
),
),
Expanded(
child: FloatingActionButton(
onPressed: () {},
child: Text(myObject.unknownUntilRunTimeText),
),
),
],
);
How do you make sure that text auto-fits (shrinks, presumably) to fit the button?
I tried to use FittedBox, but what it appears is happening in this case is that the FABS effective width is larger than the FAB (due to the expansion in a row, presumably)... and so even if you resize the text, it is still too large:
The vertical scribbles indicate where I assume Flutter is considering where the edges are.

Use FittedBox.
Example
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: Center(
child: Container(),
),
floatingActionButton: FloatingActionButton(
onPressed:(){},
child: FittedBox(
child: Text("Your text")
),
),
),
);
}
}

You can use FloatingActionButtom.extended()

Related

How to make floating widget flutter?

I want to make a floating widget but not floating all the time, when the widget is pulled up from the floating navigation bar it will appear like the picture in the middle
How to make a widget like this middle image?
this sample code of flutter for using showBottomSheet:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const MyStatelessWidget(),
),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({super.key});
#override
Widget build(BuildContext context) {
return Center(
child: ElevatedButton(
child: const Text('showBottomSheet'),
onPressed: () {
Scaffold.of(context).showBottomSheet<void>(
(BuildContext context) {
return Container(
height: 200,
color: Colors.amber,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Text('BottomSheet'),
ElevatedButton(
child: const Text('Close BottomSheet'),
onPressed: () {
Navigator.pop(context);
},
),
],
),
),
);
},
);
},
),
);
}
}
You can also try using sliding_up_panel to get the same functionality.
It is pretty straight forward to implement and offers plenty customization features as well:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("SlidingUpPanelExample"),
),
body: Stack(
children: <Widget>[
Center(child: Text("This is the Widget behind the sliding panel"),),
SlidingUpPanel(
panel: Center(child: Text("This is the sliding Widget"),),
)
],
)
);
}
Try the Stack variant so that it doesn't hinder too much with your current code.

PopupMenuButton that looks like ElevatedButton in flutter

I'm a beginer of flutter and trying to write a code to display a button that looks like ElevatedButton and displays popup when it is tapped.
I wrote a code like below but didn't work.
Does anyone know how to solve this problem?
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: const Text('Welcome to Flutter'),
),
body: Center(
child: PopupMenuButton(
itemBuilder: (context) => [
PopupMenuItem(
child: Column(
children: const [Text('item1'), Text('item2')]))
],
child: ElevatedButton(
onPressed: () {},
child: const Text('show popup menu'),
))),
),
);
}
}
It's possible to show the popup menu programmatically by calling PopupMenuButtonState.showButtonMenu(). And to get a reference to PopupMenuButtonState use a GlobalKey.
The code is going to be like this:
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
final _popupMenu = GlobalKey<PopupMenuButtonState>(); // <- Here
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: Center(
child: PopupMenuButton(
key: _popupMenu, // <- Here
itemBuilder: (context) => [
PopupMenuItem(
child: Column(children: const [Text('item1'), Text('item2')]))
],
child: ElevatedButton(
onPressed: () {
_popupMenu.currentState?.showButtonMenu(); // <- Here
},
child: const Text('show popup menu'),
),
),
),
),
);
}
}

Why does changing the background color of the navigation bar in Cupertino App change the height?

I have a widget demonstrating the rendering of a Flutter app. As it's written below, the text is visible right underneath the navigationBar. However, if you comment out the backgroundColor, it becomes invisible. Why is that?
import 'package:flutter/cupertino.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 CupertinoApp(
home: CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text("Settings"),
previousPageTitle: "Back",
backgroundColor: Colors.blue,
),
child: Column(
children: const <Widget>[
Text("Hello World!"),
],
),
),
);
}
}
Without blue color:
With blue color:
The height is not changing with the backgroundColor, here's what CupertinoPageScaffold's documentation says:
Content can slide under the navigationBar when they're translucent. In
that case, the child's BuildContext's MediaQuery will have a top
padding indicating the area of obstructing overlap from the
navigationBar.
This is why your text is hidden, it's simply going under the bar when its color is translucent. By using Colors.blue you will have an opaque color.
You can try by using backgroundColor: Colors.transparent the result will be the same as putting no color.
To fix this behavior you can wrap your Column with a SafeArea widget:
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return CupertinoApp(
home: CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text("Settings"),
previousPageTitle: "Back",
),
child: SafeArea(
child: Column(
children: const <Widget>[
Text("Hello World!"),
],
),
),
),
);
}
}
Try the full example on DartPad
#GuillaumeRoux has clarify the reason. You can fix it by SafeArea if translucent color is required.
CupertinoApp(
home: CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text("Settings"),
previousPageTitle: "Back",
),
child: SafeArea(
child: Column(
children: const <Widget>[
Text("Hello World!"),
],
)
),
),
);

Flutter: Undock the FAB in BottomSheet

I have read the flutter documentations and I have a specific widget behavior I need to implement. However I wasn't able to reproduce it. I would like to undock the floating action button in the bottom sheet. I thought it would be easy with the use of
floatingActionButtonLocation: FloatingActionButtonLocation.startFloat,
Unfortunately it only works on the BottomNavigationBar not in the BottomSheet.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Text('loc'),
),
floatingActionButtonLocation: FloatingActionButtonLocation.startFloat,
appBar: AppBar(title: const Text(_title)),
body: const MyStatelessWidget(),
),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: ElevatedButton(
child: const Text('showModalBottomSheet'),
onPressed: () {
Scaffold.of(context).showBottomSheet((BuildContext context){
return Container(
height: 200,
color: Colors.amber,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Text('Modal BottomSheet'),
ElevatedButton(
child: const Text('Close BottomSheet'),
onPressed: () => Navigator.pop(context),
)
],
),
),
);
},
);
},
),
);
}
}
But my expected result should be the FAB is undocked/floating in the bottom sheet instead of being docked. I don't want to overwork myself for this behavior by making my own implementation of bottom sheet or via gesture widget as much as possible. But if its really necessary I would like some advice or answer in this regards. Thank you and advance.
I have created the widget behavior I wanted. Please refer to the answer in this post. The answer has opened up a lot of new ideas and other flexible implementations.
Move up floating action button
Closing the issue.

Flutter get text from widgets

I am coming from java and now making my very initial steps with flutter.
In my first application I am playing around with the layouts and the buttons and I am facing difficulties getting the button actions to work, probably due to my coming from from java.
In my app I have, among others, the following widgets:
Widget _buttonOne = RaisedButton(
onPressed: () {},
child: Text('Button One', style: TextStyle(fontSize: 20)),
);
final _textContainer =
const Text('Container One', textAlign: TextAlign.center);
Container(
padding: const EdgeInsets.all(8),
child: _textContainer,
color: Colors.teal[200],
),
Now I want to print the text of the button and textchild of the container. How do I achieve that?
CupertinoButton.filled(
child: Text('Button Two'),
onPressed: () {
print(_textContainer); // how do I print the text of the text widget here?
print (_buttonOne. ....); // on java there is a getText() method .... how does this work in flutter?
),
You can access the text of a Text widget by using the data property:
final _textContainer =
const Text('Container One', textAlign: TextAlign.center);
#override
Widget build(BuildContext context) {
return Scaffold(body:
Center(
child: CupertinoButton.filled(
child: Text('Button Two'),
onPressed: () =>
{print(_textContainer.data)},
)
)
);
}
In a similar fashion, you could access the content of the RaisedButton child:
final _raisedButtonText = const Text('Button One', style: TextStyle(fontSize: 20));
Widget _buttonOne = RaisedButton(onPressed: () {}, child: _raisedButtonText);
final _textContainer =
const Text('Container One', textAlign: TextAlign.center);
#override
Widget build(BuildContext context) {
return Scaffold(body:
Center(
child: CupertinoButton.filled(
child: Text('Button Two'),
onPressed: () {
print(_textContainer.data);
print(_raisedButtonText.data);
}
)
)
);
}
You can copy paste run full code below
You can use as to do type casting then access attribute data
code snippet
CupertinoButton.filled(
child: Text('Button Two'),
onPressed: () {
print(_textContainer.data);
print(((_buttonOne as RaisedButton).child as Text).data);
}),
output
I/flutter (30756): Container One
I/flutter (30756): Button One
full code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Widget _buttonOne = RaisedButton(
onPressed: () {},
child: Text('Button One', style: TextStyle(fontSize: 20)),
);
final _textContainer =
const Text('Container One', textAlign: TextAlign.center);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CupertinoButton.filled(
child: Text('Button Two'),
onPressed: () {
print(_textContainer
.data); // how do I print the text of the text widget here?
print(((_buttonOne as RaisedButton).child as Text).data);
}),
],
),
),
);
}
}