I have TextFild and ElevatedButton, by default TextFild is empty and ElevatedButton has one color set, when entering some text, I would like to change the color of ElevatedButton to another. I tried to write a condition for this, where the variable would change depending on the state, but MaterialStateProperty does not work with Color, and declaring it Final I cannot change it. How do I declare a variable to work with MaterialStateProperty ?
final _textController = TextEditingController();
void _login (){
final worldColor = _textController.text;
if (worldColor == null){
} else {
setState(() {
});
}
}
@override
Widget build(BuildContext context) {
final colorButton = MaterialStateProperty.all (Color.fromARGB(255, 157, 186, 219));
final decorationRow = const InputDecoration(border: OutlineInputBorder(), contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 10), isCollapsed: true, hintText: "Email",filled: true, fillColor: Color.fromARGB(255, 236, 236, 236), hintStyle: TextStyle(fontSize: 15, color: Color.fromARGB(255, 145, 144, 144)), );
final richBotton = const TextStyle(color: Color.fromARGB(255, 117, 117, 117), fontSize: 11,); // textAlign: TextAlign.center;
final text = const TextStyle(color: Colors.grey, fontSize: 11);
return Padding(
padding: const EdgeInsets.symmetric(vertical: 15),
child: Column(
children: [
TextField(controller: _textController,decoration: decorationRow,),
SizedBox(height: 15),
ElevatedButton(
onPressed: () {
setState(() {
colorButton = MaterialStateProperty.all (Color.fromARGB(255, 157, 186, 219));
});
},
style: ButtonStyle(backgroundColor: colorButton, minimumSize: MaterialStateProperty.all (Size.fromHeight(1)),
foregroundColor: MaterialStateProperty.all (Colors.white),
textStyle: MaterialStateProperty.all (
TextStyle(
fontSize: 16, fontWeight: FontWeight.w500)),
padding: MaterialStateProperty.all (EdgeInsets.symmetric(horizontal: 10, vertical: 10))),
child: Text ('Next')),
This is how it looks without text
This is how I would like it to look when entering text
CodePudding user response:
You can use a stateful widget for that. It's better to have a TextField
with a textController
and a FocusNode
. Then you can change the color of the button depending on whether the textController.text
is empty or not.
Here is a sample code to illustrate what I said:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _textController = TextEditingController();
final _focusNode = FocusNode();
Color get buttonColor =>
_textController.text.isNotEmpty ? Colors.green : Colors.grey;
@override
void dispose() {
_textController.dispose();
_focusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
focusNode: _focusNode,
controller: _textController,
decoration: InputDecoration(
border: OutlineInputBorder(),
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
isCollapsed: true,
hintText: "Email",
filled: true,
fillColor: Color.fromARGB(255, 236, 236, 236),
hintStyle: TextStyle(
fontSize: 15,
color: Color.fromARGB(255, 145, 144, 144),
),
),
),
SizedBox(height: 15),
ElevatedButton(
onPressed: _textController.text.isNotEmpty
? () {
_textController.clear();
_focusNode.unfocus();
}
: null,
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(buttonColor),
minimumSize: MaterialStateProperty.all(Size.fromHeight(1)),
foregroundColor: MaterialStateProperty.all(Colors.white),
textStyle: MaterialStateProperty.all(
TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
padding: MaterialStateProperty.all(
EdgeInsets.symmetric(horizontal: 10, vertical: 10),
),
),
child: Text('Next'),
),
],
),
);
}
}
I hope it helps.
CodePudding user response:
Ok From the example i have create an example for you :
Basically using the
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Test App',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _textController = TextEditingController();
final _formKey = GlobalKey<FormState>();
// Color red is button is disabled and green is enabled. you can change as per you requirement.
final successColor = MaterialStateProperty.all(Colors.green);
final errorColor = MaterialStateProperty.all(Colors.red);
final decorationRow = const InputDecoration(
border: OutlineInputBorder(),
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
isCollapsed: true,
hintText: "Email",
filled: true,
fillColor: Color.fromARGB(255, 236, 236, 236),
hintStyle: TextStyle(fontSize: 15, color: Color.fromARGB(255, 145, 144, 144)),
);
final richBotton = const TextStyle(
color: Color.fromARGB(255, 117, 117, 117),
fontSize: 11,
); // textAlign: TextAlign.center;
final text = const TextStyle(color: Colors.grey, fontSize: 11);
bool isValid = false;
@override
void initState() {
super.initState();
_textController.addListener(() {
if (_textController.text.isEmpty) {
setState(() {
isValid = false;
});
} else {
setState(() {
isValid = true;
});
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('sample'),
),
body: Form(
key: _formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
TextFormField(
controller: _textController,
decoration: decorationRow,
validator: (value) {
if (value!.isEmpty) {
return "please enter some data";
} else {
return null;
}
},
),
SizedBox(height: 15),
ElevatedButton(
onPressed: !isValid
? null
: () {
// go further.
},
style: ButtonStyle(
backgroundColor: isValid ? successColor : errorColor,
minimumSize: MaterialStateProperty.all(Size.fromHeight(1)),
foregroundColor: MaterialStateProperty.all(Colors.white),
textStyle:
MaterialStateProperty.all(TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
padding: MaterialStateProperty.all(EdgeInsets.symmetric(horizontal: 10, vertical: 10))),
child: Text('Next')),
],
),
),
),
);
}
}
you can change the color of button as per your needs
This will change dynamically, when you type in the field.
This is the UI output:
Let me know this works for you