Flutter: Change button color on TextField focus

5,080

Solution 1

Please check the below code , i have use the Focus widget for it, it has the onFocusChange which will indicate the TextField is selected or not

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutterlearningapp/colors.dart';

class HomeScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _HomeScreen();
  }
}

class _HomeScreen extends State<HomeScreen> {
  bool isTextFiledFocus = false;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Demo",
      home: Scaffold(
        appBar: AppBar(
          title: Text("List"),
        ),
        body: Container(
          margin: EdgeInsets.all(20.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              Focus(
                child: TextFormField(
                  textInputAction: TextInputAction.next,
                  decoration: InputDecoration(labelText: "Input 1"),
                ),
                onFocusChange: (hasFocus) {
                  setState(() {
                    isTextFiledFocus = hasFocus;
                  });
                },
              ),

              TextFormField(
                textInputAction: TextInputAction.next,
                decoration: InputDecoration(labelText: "Input 1"),
              ),
              RaisedButton(
                color: isTextFiledFocus ? Colors.pink : Colors.blue,
                child: Text("Ok"),
                onPressed: () {
                  print("I am clicked");
                },
              )
            ],
          ),
        ),
      ),
    );
  }
}

And check the below output of it
enter image description here

Solution 2

myFocusNode.requestFocus(); inside setState? Ps. Yep it worked for me

myFocusNode = FocusNode();
myFocusNode.addListener(() {
  setState(() {
    if(myFocusNode.hasFocus) {
      myFocusNode.requestFocus();
    }
  });
});

Ps2: @Ravindra Kushwaha answer is better :)

Share:
5,080
rgisi
Author by

rgisi

Updated on December 20, 2022

Comments

  • rgisi
    rgisi over 1 year

    I have a text field and a separate button, I want to change the button's color when the text field focuses.

    Naively, I would like to write: FlatButton(..., backgroundColor: myFocusNode.hasFocus ? Colors.red : Colors.green). This, of course, does not work as the Button doesn't get notified about the focus change. Alternatively, I tried to add a Listener to myFocusNode, but if I try to call setState inside it in order to rebuild the button, the text field loses it's focus again.

    I modified the sample code from the respective cookbook to illustrate, you can copy the code below and paste and run to see what I mean. How can i make the button turn red when clicking the text field?

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Text Field Focus',
          home: MyCustomForm(),
        );
      }
    }
    
    // Define a custom Form widget.
    class MyCustomForm extends StatefulWidget {
      @override
      _MyCustomFormState createState() => _MyCustomFormState();
    }
    
    // Define a corresponding State class.
    // This class holds data related to the form.
    class _MyCustomFormState extends State<MyCustomForm> {
      // Define the focus node. To manage the lifecycle, create the FocusNode in
      // the initState method, and clean it up in the dispose method.
      FocusNode myFocusNode;
    
      @override
      void initState() {
        super.initState();
    
        myFocusNode = FocusNode();
      }
    
      @override
      void dispose() {
        // Clean up the focus node when the Form is disposed.
        myFocusNode.dispose();
    
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Text Field Focus'),
          ),
          body: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              children: [
                // The first text field is focused on as soon as the app starts.
                TextField(
                  autofocus: true,
                ),
                // The second text field is focused on when a user taps the
                // FloatingActionButton.
                TextField(
                  focusNode: myFocusNode,
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            // When the button is pressed,
            // give focus to the text field using myFocusNode.
            onPressed: () => myFocusNode.requestFocus(),
            tooltip: 'Focus Second Text Field',
            backgroundColor: myFocusNode.hasFocus ? Colors.red : Colors.green,
            child: Icon(Icons.edit),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    }
    
    • Ravindra Kushwaha
      Ravindra Kushwaha about 4 years
      @rgissi, Have yoou checked the below solution, let me know in case of concern
    • rgisi
      rgisi almost 4 years
      Hi Ravindra, Thank you for answering, and sorry for being slow. My development work was interrupted and I'll now resume and comment on your answer.
    • Ravindra Kushwaha
      Ravindra Kushwaha almost 4 years
      Ok , let me know in case of concern...And if the answer is workable for you then please accept it as useful for the future users
  • rgisi
    rgisi almost 4 years
    Thank you, Ravindra! This does indeed solve the problem, and using the Focus widget is very elegant. Unfortunately, it creates a problem for me (but apparently not for you): On focus, the keyboard and the cursor disappear because I call setState inside onFocusChange... :-( Any idea how to solve this, maybe?
  • rgisi
    rgisi almost 4 years
    Thank you! This works as well, but just as @Ravindra Kushwaha's solution it has the problem that the keyboard immediately disappears again if I call setState... thanks for any ideas on how to solve this.
  • rgisi
    rgisi almost 4 years
    Alright, the keyboard problem was something different and is now solved as well: github.com/flutter/flutter/issues/20042 Thanks for your help!
  • rgisi
    rgisi almost 4 years
    Alright, the keyboard problem was something different and is now solved as well: github.com/flutter/flutter/issues/20042 Thanks for your help!
  • Ravindra Kushwaha
    Ravindra Kushwaha almost 4 years
    Happy to help you man!!! Keep happy coding..please upvote it also