Home > Mobile >  How to change the color of ElevatedButton when entering text in TextField
How to change the color of ElevatedButton when entering text in TextField

Time:07-02

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

  • Related