Flutter TextField value disappear when clicked on another textField - flutter

Am New in Flutter, Now am trying to add ModalBottomSheet with some textfields and whenever i try to tap on another textField then value got disappeared automatically.
Here is my new_user.dart file
import 'package:flutter/material.dart';
class newUsers extends StatelessWidget {
var nameInputController = TextEditingController();
var marksInputController = TextEditingController();
Function? addNewUser;
newUsers(this.addNewUser);
void submitData() {
print(nameInputController.text);
if (nameInputController.text.isEmpty || marksInputController.text.isEmpty) {
return;
}
addNewUser!(
nameInputController.text, double.parse(marksInputController.text));
}
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextField(
decoration: InputDecoration(labelText: "Name"),
controller: nameInputController,
),
TextField(
decoration: InputDecoration(labelText: "Marks"),
controller: marksInputController,
keyboardType: TextInputType.number,
),
ElevatedButton(
onPressed: submitData,
child: Text('Add User Details'),
),
],
),
);
}
}
Home.dart
import 'package:expense_manager/widgets/new_users.dart';
import 'package:expense_manager/widgets/users.dart';
import 'package:expense_manager/widgets/users_list.dart';
import 'models/users.dart';
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
List<User> users = [
User(id: 1, name: 'himanshurahi', marks: 44.5, createdAt: DateTime.now()),
];
void addNewUser(String name, double marks) {
var newUser =
User(id: 1, name: name, marks: marks, createdAt: DateTime.now());
setState(() {
users.add(newUser);
});
}
#override
Widget build(BuildContext context) {
void addNewUserWithSheet(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (btx) {
return newUsers(addNewUser);
},
);
}
return Scaffold(
appBar: AppBar(
title: Text('my App'),
actions: [
IconButton(
onPressed: () => addNewUserWithSheet(context),
icon: Icon(Icons.add))
],
),
floatingActionButton: FloatingActionButton(
onPressed: () => addNewUserWithSheet(context),
child: Icon(Icons.add)),
body: Container(
child: Column(
children: [
Container(
width: double.infinity,
height: 100,
child: Card(
color: Colors.blueAccent,
child: Text("Chart"),
),
),
newUsers(addNewUser),
usersList(users)
],
),
));
}
}
Here i have added addNewUserWithSheet method to add bottom sheet.
here is main.dart file (if need)
import 'package:expense_manager/home.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Home(),
);
}
}
Thanx in advance :)

Ahhh I Basically solved it by using Stateful Widget.

Related

flutter Change part of text selected color in textfield

I want when the user selects a part of the text in textfield and clicks on the color button, only that part of the selected text will be colored.
Thanks
I searched all the articles but couldn't find any results.
Nima jan Salaam,
you need to use rich_text_controller package like this code below:
first of all add rich_text_controller: ^1.4.0 in your pubspec.yaml (or any compatible versions).
import 'package:flutter/material.dart';
import 'package:rich_text_controller/rich_text_controller.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: RichTextControllerDemo(),
);
}
}
class RichTextControllerDemo extends StatefulWidget {
const RichTextControllerDemo({super.key});
#override
State<RichTextControllerDemo> createState() => _RichTextControllerDemoState();
}
class _RichTextControllerDemoState extends State<RichTextControllerDemo> {
RichTextController? _controller;
#override
void initState() {
_controller = RichTextController(
stringMatchMap: {
"test": const TextStyle(color: Colors.red),
},
onMatch: (List<String> matches){
}
);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: _controller,
onChanged: (value){
},
),
Padding(
padding: const EdgeInsets.only(top : 20.0),
child: InkWell(
child: const Text('click'),
onTap: (){
var start = _controller!.selection.start;
var end = _controller!.selection.end;
var text = _controller!.text.substring(start,end);
setState(() {
_controller!.stringMatchMap!.addAll(
{
text : const TextStyle(color: Colors.cyan),
}
);
});
},
),
)
],
)),
);
}
}
happy coding bro...

What argument should i give?

In the application, the home page is ResultScreen, which displays the entered data. If they are not there, then when you click on the button, we go to the screen with the input. When I enter text into the input and click on the Display Result button, the data should be substituted into the text field on the first screen. I implemented such functionality, but I don’t understand what argument I should substitute in main.dart. Tell me please
Text Screen:
import 'package:flutter/material.dart';
import 'package:flutter_application_1/screens/result_screen.dart';
class TextScreen extends StatefulWidget {
const TextScreen({Key? key}) : super(key: key);
#override
State<TextScreen> createState() => _TextScreenState();
}
class _TextScreenState extends State<TextScreen> {
TextEditingController textController = TextEditingController();
#override
void dispose() {
textController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Enter data'),
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: textController,
decoration: InputDecoration(labelText: 'Message'),
),
const SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ResultScreen(textController.text)));
},
child: Text('Display result'))
],
)),
);
}
}
Result Screen:
import 'package:flutter/material.dart';
import 'package:flutter_application_1/screens/text_screen.dart';
class ResultScreen extends StatefulWidget {
final String valueText;
ResultScreen(this.valueText);
#override
State<ResultScreen> createState() => _ResultScreenState();
}
class _ResultScreenState extends State<ResultScreen> {
// navigation to text_screen
void _buttonNav() {
Navigator.push(
context, MaterialPageRoute(builder: (context) => const TextScreen()));
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Results'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: _buttonNav, child: const Text('Enter data')),
const SizedBox(
height: 50,
),
Text(valueText),
const SizedBox(
height: 20,
),
],
)),
);
}
}
Main.dart:
import 'package:flutter/material.dart';
import 'package:flutter_application_1/screens/result_screen.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',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ResultScreen(),
);
}
}
Use the following code.
What is does is, when we enter the first screen i.e. ResultScreen, we pass an empty value for the first time.
Use this in main.dart
home: ResultScreen(''),
And as you are using statefull widget for ResultScreen, you need to use widget.valueText to access it like:
Text(widget.valueText),

How do i print the value which is coming from modal bottom sheet to the main scaffold body in dart+flutter

ive created a text and icon button, onpressing that icon
modal bottom sheet gets generated, in that
and ive created a separate dart file with text field and a submit button
when giving an input on text field and after clicking on submit button the given input string will be printed below
atlast i called the function in first dart file
but i want the text to be printed on the main scaffold page.
Below is the main code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:practice1/StatefulModalbtn.dart';
void main() {
runApp(Modalbtn());
}
class Modalbtn extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Modal Bottom Test'),
),
body: Column(
children: <Widget>[Mymodal()],
),
),
);
}
}
class Mymodal extends StatelessWidget {
const Mymodal({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
'Press the icon to select the Tractor model',
style: TextStyle(fontSize: 15),
),
IconButton(
onPressed: () {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return Container(
height: 200,
child: Column(
children: <Widget>[StatefulModalbtn()],
),
);
});
},
icon: Icon(Icons.add),
iconSize: 20,
)
],
),
);
}
}
and below code is for creating a text field and submit button
import 'package:flutter/material.dart';
class StatefulModalbtn extends StatefulWidget {
const StatefulModalbtn({Key? key}) : super(key: key);
#override
_StatefulModalbtnState createState() => _StatefulModalbtnState();
}
class _StatefulModalbtnState extends State<StatefulModalbtn> {
TextEditingController textController = TextEditingController();
String displayText = "";
#override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
controller: textController,
maxLines: null,
),
ElevatedButton(
onPressed: () {
setState(() {
displayText = textController.text;
});
},
child: Text('Submit')),
Text(
displayText,
style: TextStyle(fontSize: 20),
),
],
);
}
}
and below is the output link
this is the output im achieving but i want the "Hello World" to be printed on top/main screen, right after the + add icon screen
How should i solve this ??
I just slightly edited your code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'main1.dart';
void main() {
runApp(MaterialApp(
home: Modalbtn(),
));
}
class Modalbtn extends StatefulWidget {
#override
_ModalbtnState createState() => _ModalbtnState();
}
class _ModalbtnState extends State<Modalbtn> {
String value = "0";
// Pass this method to the child page.
void _update(String newValue) {
setState(() => value = newValue);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
IconButton(
onPressed: () {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return Container(
height: 200,
child: Column(
children: [StatefulModalbtn(update: _update)],
),
);
});
},
icon: Icon(Icons.add),
iconSize: 20,
),
Text(
value,
style: TextStyle(fontSize: 40),
),
],
),
),
);
}
}
and the child class is
import 'package:flutter/material.dart';
class StatefulModalbtn extends StatelessWidget {
final ValueChanged<String> update;
StatefulModalbtn({required this.update});
#override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () => update("100"), // Passing value to the parent widget.
child: Text('Update (in child)'),
);
}
}

How to update screen when instance of external stateful widget class is updated

I am displaying the weight of an instance of a person class on my homepage. When I update the weight of this instance through a form in a popup bottom sheet the displayed weight is only changed after a hot reload. How can I trigger a setState in my person class when its instances parameters are changed in homepage?
main.dart
import 'package:flutter/material.dart';
import 'package:metricwidget/screens/homepage.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// Root of application
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const Homepage(),
);
}
}
person.dart
import 'package:flutter/material.dart';
class person extends StatefulWidget {
int? weight;
person({Key? key, this.weight}) : super(key: key);
void updateWeight(newWeight){
weight = newWeight;
}
#override
_personState createState() => _personState();
}
class _personState extends State<person> {
#override
Widget build(BuildContext context) {
return Center(
child: Text(
widget.weight.toString(),
style: const TextStyle(fontSize: 24),
),
);
}
}
homepage.dart
import 'package:mvs/person.dart';
import 'package:flutter/material.dart';
class Homepage extends StatefulWidget {
const Homepage({Key? key}) : super(key: key);
#override
_HomepageState createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
var joe = person(weight: 23);
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Material(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: joe,
),
OutlinedButton(
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) {
return Form(
key: _formKey,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
onSaved: (String? value) {
if (int.parse(value!) > 0) {
setState(() {
joe.updateWeight(int.parse(value));
});
}
},
keyboardType: TextInputType.number,
maxLength: 3,
initialValue: joe.weight.toString(),
decoration: const InputDecoration(
icon: Icon(Icons.label),
),
validator: (value) {
if (value!.isEmpty) {
return "Please enter value";
}
return null;
},
),
),
OutlinedButton(
onPressed: () {
_formKey.currentState!.save();
Navigator.pop(context);
},
child: const Text("submit"),
)
],
),
);
},
);
},
child: const Text("Update"),
)
],
),
);
}
}
Was able to solve this using provider and changenotifier, same as the format outlined in the docs below
Reference: https://pub.dev/packages/provider

How can I get the input of my textfield inside my custom dialog widget?

I am working on a custom dialog called "Alertbox" where the user inserts a name into a textfield and after he pushes the button a function called "addTeam" created a team out of the string.
This is how I created my dialog "Alertbox":
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:trainings_app/config/palette.dart';
class Alertbox extends StatelessWidget {
final Function addTeamFunction;
const Alertbox(this.addTeamFunction);
#override
Widget build(BuildContext context) {
return Dialog(
backgroundColor: Colors.transparent,
elevation: 0,
insetPadding: EdgeInsets.all(10),
child: Center(
child: Container(
decoration: new BoxDecoration(
borderRadius: new BorderRadius.all(const Radius.circular(20)),
color: Colors.white,
),
width: 350,
height: 200,
child: Row(
children: [
SizedBox(width: 12),
Expanded(
child: TextField(
textAlign: TextAlign.center,
autofocus: true,
),
),
SizedBox(width: 12),
ElevatedButton(
onPressed: () => addTeamFunction(),
child: const Text('✓'),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Palette.orange),
),
),
SizedBox(width: 8),
],
),
),
),
);
}
}
And here I am using it:
void newTeam() {
showDialog<AlertDialog>(
context: context,
builder: (BuildContext context) {
return Alertbox(() {
Navigator.of(context).pop();
});
},
);
}
void addTeam(String name) {
setState(() {
teams.add(name);
});
Navigator.of(context).pop();
sharedPreferences.setStringList('teams', teams);
}
But I can't find a way to parse the input from the textfield into the function "addTeam" where it is needed. Can anyone help me please?
You Should try below code hope its helps you:
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 const MaterialApp(
title: 'Testing',
home: MyCustomForm(),
);
}
}
class MyCustomForm extends StatefulWidget {
const MyCustomForm({Key? key}) : super(key: key);
#override
_MyCustomFormState createState() => _MyCustomFormState();
}
class _MyCustomFormState extends State<MyCustomForm> {
final myController = TextEditingController();
#override
void dispose() {
myController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Retrieve Text Input'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: myController,
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text(myController.text),
);
},
);
},
tooltip: 'Show the value!',
child: const Icon(Icons.add),
),
);
}
}
Your Screen like ->
Use a TextFormField instead of a TexiField widget contained in a Form widget that has a GlobalKey, which will be useful to you during validation!
How to get the value which is already entered on the keyboard?
Uses a TextEditingController or the onSaved method of the TextFormField.