Flutter get text from widgets - flutter

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);
}),
],
),
),
);
}
}

Related

Unable to navigate from GetX Dialog to another screen

I have follow dialog box. When I click 'Next' I want it to navigate to GamePage() screen. But unfortunately it doesn't work.
Following is the GamePage Widget
class GamePage extends StatelessWidget {
final homeCtrl = Get.find<HomeController>();
GamePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF8fb1ca),
body: SafeArea(
child: ListView(
children: [
Padding(
padding: EdgeInsets.all(3.0.wp),
child: Row(
children: [
IconButton(
onPressed: () {
Get.back();
},
icon: const Icon(Icons.arrow_back),
),
],
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 4.0.wp),
child: Column(
children: [
SizedBox(
height: 2.0.wp,
),
Center(
child: Text(
'What ${homeCtrl.currentWord.first.wordtype} is this?',
style: TextStyle(
fontSize: 18.0.sp,
color: Colors.grey[800],
),
),
),
SizedBox(height: 10.0.wp),
WordsWidget(currentWord: homeCtrl.currentWord.first),
],
),
),
],
),
),
);
}
}
Following is the Word Widget being called from GamePage Widget
class WordsWidget extends StatelessWidget {
final currentWord;
WordsWidget({Key? key, this.currentWord}) : super(key: key);
final homeCtrl = Get.find<HomeController>();
#override
Widget build(BuildContext context) {
// var currentWord = homeCtrl.nextWord();
var shuffleword = [].obs;
shuffleword.addAll(homeCtrl.shuffleWord(currentWord.word));
TextToSpeech tts = TextToSpeech();
String language = 'en-US';
tts.setLanguage(language);
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
print('pressed here');
Get.defaultDialog(
title: 'Go to next page',
content: Container(
child: Column(
children: [
Text('You are about to move to another screen'),
ElevatedButton.icon(
onPressed: () {
Get.to(() => GamePage());
},
icon: Icon(
Icons.arrow_right,
),
label: Text('Go'))
],
),
));
},
child: Text('Open Dialog')),
],
);
}
}
Get.back() is working but not Get.to
Try
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) {
return const GamePage();
},
),
);
},
child: Text("Next Word"),
)
Try this code -
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:image_memory/next_page.dart';
import 'package:image_picker/image_picker.dart';
void main() {
//check getMaterialApp is used
runApp(const GetMaterialApp(
title: 'Temp',
home: const MyApp(),
));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Image Picker'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
print('pressed here');
Get.defaultDialog(
title: 'Go to next page',
content: Container(
child: Column(
children: [
Text('You are about to move to another screen'),
ElevatedButton.icon(
onPressed: () {
Get.to(() => NextPage());
},
icon: Icon(
Icons.arrow_right,
),
label: Text('Go'))
],
),
));
},
child: Text('Open Dialog')),
),
);
}
}
and next page is -
import 'package:flutter/material.dart';
class NextPage extends StatefulWidget {
const NextPage({ Key? key }) : super(key: key);
#override
State<NextPage> createState() => _NextPageState();
}
class _NextPageState extends State<NextPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Next Page'),
),
body: Container(
child: Center(
child: Text("this is next page"),
),
),
);
}
}
And yes, you need to insure that you are using 'GetMaterialApp'.
If you want to use GetX navigation system, you should wrap your application in a GetMaterialApp instead of MaterialApp.
So in your main use this:
class GetxApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return GetMaterialApp(
home: HomePage(),
);
}
}
Instead of this:
class NormalApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}

Flutter Floating Action Button issue in opening SimpleDialog or Bottom Sheet

I have a Main Dart File with the Bottom Navigation bar and Floating action button.
I am trying to open SimpleDialog or showModalBottomSheet when the user taps on the Button. But this is not working.
I have tried another way to open it. But that also does not work.
I am sure the problem is with the context. With the right context, the dialog should get open.
What's the right solution to tackle this As if this floating action button is added in one of the Screens from the Bottom navigation then the BottomSheetModal gets opened.
Navigator.of(context).push(new MaterialPageRoute<Null>(
builder: (BuildContext context) {
return SimpleDialog(
title:Text("hello"),
);
},
fullscreenDialog: true
));
}
Sample code can be found here
https://github.com/parmarravi/Flutter-BottomSheet-Bug
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> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
showDialog(
context: context,
builder: (context) {
return AlertDialog(
backgroundColor: Color(0xFFFFFFDD),
shape: RoundedRectangleBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(20),
),
side: BorderSide(
color: Theme.of(context).primaryColor,
width: 2,
),
),
title: Column(
children: [
Text(
'title',
),
],
),
content: Container(
child: Text(
'body!',
),
),
actions: [
Container(
height: 50,
child: TextButton(
onPressed: (){},
child: Text(
'Ok',
),
),
)
],
);
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

Flutter Web: How to fix SelectableText alignment?

I have a SelectableText and Icon inside a Row, but SelectableText does not seem to be properly aligned.
Right now it looks like this,
Expected Result:
This is code I am using,
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Icon(FontAwesomeIcons.whatsapp),
const Padding(padding: EdgeInsets.only(left: 8)),
SelectableText(
'+91-8**2**8**5',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.title,
)
],
),
PS: It works well with Text but I want SelectableText instead.
Issue Selectabletext widget on web is cutted on half
https://github.com/flutter/flutter/issues/40663 has been solved.
please upgrade to latest version
attached my full test code and result
full test code
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#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> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Icon(FontAwesomeIcons.whatsapp),
const Padding(padding: EdgeInsets.only(left: 8)),
SelectableText(
'+91-8**2**8**5',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.title,
)
],
),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

How to add navigation route to Card in Flutter

In the code below, I have a method myMenu on a card. How do I navigate to another page when the card is tapped? There are going to be several of these cards which will link to its own page content. Each time I add a function to for an example it gives an error. How do I do it properly?
import 'package:flutter/material.dart';
import 'package:tarjous_app/gridview_demo.dart';
void main(List<String> args) {
runApp(
new MaterialApp(home: TarjousAle(), debugShowCheckedModeBanner: false));
}
class TarjousAle extends StatefulWidget {
#override
_TarjousAleState createState() => _TarjousAleState();
}
class _TarjousAleState extends State<TarjousAle> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: Text("Study Plan"),
backgroundColor: Colors.amber,
),
body: Container(
child: GridView.count(
crossAxisCount: 3,
children: <Widget>[
MyMenu(
title: "Records",
icon: Icons.account_balance_wallet,
shape: Colors.brown,
),
MyMenu(
title: "Academy",
icon: Icons.account_balance,
shape: Colors.grey,
),
],
),
),
);
}
}
class MyMenu extends StatelessWidget {
MyMenu({this.title, this.icon, this.shape});
final String title;
final IconData icon;
final MaterialColor shape;
#override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.all(9.0),
child: InkWell(
onTap: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => GridViewDemo()),
),
splashColor: Colors.amberAccent,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
icon,
size: 80.0,
color: shape,
),
Text(title, style: new TextStyle(fontSize: 18.0))
],
),
),
),
);
}
}
In the inkwell widget, I add a function that works for all the cards. But what I really want it for each card to navigate to its own page. E.g Records should navigate to its own records page, the same thing for Academy to academy page
You could receive the page in the constructor and then go to that page, like this:
class MyMenu extends StatelessWidget {
MyMenu({this.title, this.icon, this.shape, this.page});
final Widget page;
...
}
Then, in onTap:
onTap: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => page),
)
So now you can do this:
MyMenu(
...
page: GridViewDemo1(),
),
MyMenu(
...
page: GridViewDemo2(),
)
Note that to navigate to some page, your context must contain a Navigator instance of parent. So if you try to navigate directly from MaterialApp, you might run into issues. I will not belabour the point here since it was explained very well in this thread, but it is something to keep in mind in case you happen to run into it.
Edited to address comments:
I'd do something like this for your case. Named routes make it easy to specify which route you'd like the card to take you to, which you kind of need to do if you want the same widget to take you to different routes.
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(
new MaterialApp(
home: TarjousAle(),
debugShowCheckedModeBanner: false,
routes: {
GridViewDemo.route: (context) => GridViewDemo(),
AnotherDemo.route: (context) => AnotherDemo(),
},
),
);
}
class TarjousAle extends StatefulWidget {
#override
_TarjousAleState createState() => _TarjousAleState();
}
class _TarjousAleState extends State<TarjousAle> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: Text("Study Plan"),
backgroundColor: Colors.amber,
),
body: Container(
child: GridView.count(
crossAxisCount: 3,
children: <Widget>[
MyMenu(
title: "Records",
icon: Icons.account_balance_wallet,
shape: Colors.brown,
route: GridViewDemo.route
),
MyMenu(
title: "Academy",
icon: Icons.account_balance,
shape: Colors.grey,
route: AnotherDemo.route
),
],
),
),
);
}
}
class MyMenu extends StatelessWidget {
MyMenu({this.title, this.icon, this.shape, this.route});
final String title;
final IconData icon;
final MaterialColor shape;
final String route;
#override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.all(9.0),
child: InkWell(
onTap: () => Navigator.pushNamed(context, route),
splashColor: Colors.amberAccent,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
icon,
size: 80.0,
color: shape,
),
Text(title, style: new TextStyle(fontSize: 18.0))
],
),
),
),
);
}
}
class GridViewDemo extends StatelessWidget {
static String route = '/demo';
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.brown,
appBar: AppBar(title: Text('Grid view demo')),
body: Center(
child: Text('Grid view demo'),
),
);
}
}
class AnotherDemo extends StatelessWidget {
static String route = '/another';
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(title: Text('Another demo')),
body: Center(
child: Text('Another demo'),
),
);
}
}
You can read more about the basics of navigation in official docs, and also another docs page if you fancy the named routes.
Wrap the card with GestureDetector and you can use opnTap property.
for more details Official Documentation
Try wrapping your Card in a GestureDetector like below:
GestureDetector (
child: Card(),
onTap: () {},
),
wrap the card with InkWell widget and define your navigator.push in the onTap method.
class CardWidget extends StatelessWidget {
final Function onTapCard;
const CardWidget({Key key, #required this.onTapCard}) : super(key: key);
#override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.all(9.0),
child: InkWell(
onTap: onTapCard,
splashColor: Colors.amberAccent,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
icon,
size: 80.0,
color: shape,
),
Text(title, style: new TextStyle(fontSize: 18.0))
],
),
),
),
);
}
}
then we have our list here
class CardList extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
CardWidget(
onTapCard: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => YourSecondPage()),
),
),
CardWidget(
onTapCard: Navigator.push(
context,
MaterialPageRoute(builder: (context) => YourThirdPage()),
),
),
],
);
}
}

Style clipboard in flutter

I am looking for a way to style the clipboard actions without touching textTheme/button property of the main style theme. Is this even possible?
Seems like the style is directly tied to the theme. Not the best idea but if you really wanted to you would need to create a custom popup and handle all the actions yourself.
This should get you started...
Output:
Code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#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> {
final _controller = new TextEditingController();
final _textfieldFocusNode = new FocusNode();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.all(20.0),
child: GestureDetector(
// intercept all pointer calls
behavior: HitTestBehavior.opaque,
onTap: () {
FocusScope.of(context).requestFocus(_textfieldFocusNode);
},
onLongPress: () {
showMenu(
context: context,
// TODO: Position dynamically based on cursor or textfield
position: RelativeRect.fromLTRB(0.0, 300.0, 300.0, 0.0),
items: [
PopupMenuItem(
child: Row(
children: <Widget>[
// TODO: Dynamic items / handle click
PopupMenuItem(
child: Text(
"Paste",
style: Theme.of(context)
.textTheme
.body2
.copyWith(color: Colors.red),
),
),
PopupMenuItem(
child: Text("Select All"),
),
],
),
),
],
);
},
child: IgnorePointer(
// ensures textfield doesn't overrule GestureDetector
child: TextField(
focusNode: _textfieldFocusNode,
controller: _controller,
),
),
),
)
],
),
),
);
}
}