Focus control of Flutter text input box TextField

Inscription
- Holding the sword in the world, starting from your accumulation, you will strive for perfection wherever you go.

This article was first published on the WeChat public account (biglead), my big front-end career, and published in various technical forums simultaneously.

This article reviews the acquisition and removal of the focus of the Flutter text input box TextField. In actual project development, precise control of the focus of the input box can achieve exquisite user experience.


TextField series of articles

1 Set the TextField to get the input focus directly

insert image description here
The source code is as follows:

///TextField focus acquisition control 
class  TextFeildHomePage3  extends  StatefulWidget  { 
  @override 
  State < StatefulWidget >  createState ( )  { 
    return  TextFeildHomePageState ( ) ; 
  } 
} 
class  TextFeildHomePageState  extends  State  {
 
  @override 
  Widget build ( BuildContext context )  { 
    return  Scaffold ( 
      appBar :  AppBar ( 
        title :  Text ( "TextField Explanation" ) , 
      ) , 
      body :  Container ( 
        ///SizedBox is used to limit a space with a fixed width and height 
        child :  SizedBox ( 
          width :  400 , 
          height :  100 , 
          child :  Container (
            color : Colors . white24 , 
            padding : EdgeInsets . all ( 10 ) , 
            ///Alignment is used to align Widget 
            alignment :  Alignment ( 0 ,  0 ) , 
            ///Text input box 
            child :  TextField ( 
              autofocus :  true , 
            ) , 
          ) , 
        ) , 
      ) , 
    ) ; 
  } 
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

Then run the program, and some mobile phones will have the following exception (only a part of the exception information is intercepted):

flutter: ══╡ EXCEPTION CAUGHT BY FOUNDATION LIBRARY ╞════════════════════════════════════════════════════════
flutter: The following assertion was thrown while dispatching notifications for FocusNode:
flutter: RenderBox was not laid out: RenderEditable#766b0 NEEDS-LAYOUT NEEDS-PAINT
flutter: 'package:flutter/src/rendering/box.dart':
flutter: Failed assertion: line 1687 pos 12: 'hasSize'
flutter:
flutter: Either the assertion indicates an error in the framework itself, or we should provide substantially
flutter: more information in this error message to help you determine and fix the underlying cause.
flutter: In either case, please report this assertion by filing a bug on GitHub:
flutter:   https://github.com/flutter/flutter/issues/new?template=BUG.md
flutter:
flutter: When the exception was thrown, this was the stack:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

When this exception message appears, we can understand that when the current page has not been drawn, we use TextField to obtain the input focus, and then the program responsible for focus control cannot find the focus, so an exception occurs.
Then one of our solutions The method can be to get the focus without using the autofocus attribute, and can use FocusNode to control

2 Using FocusNode in TextField

FocusNode can monitor the focus event of TextField.

2.1 Create FocusNode
FocusNode  focusNode = new FocusNode();
  • 1
2.2 Using FocusNode in TextField

TextField can be referenced through the focusNode attribute

2.3 TextField controls input focus through focusNode
///Get the focus of the input box 
FocusScope . of ( context ) . requestFocus ( focusNode ) ; 
/// Lose the focus of the input box 
focusNode . unfocus ( ) ;
  • 1
  • 2
  • 3
  • 4

In the above case, we can actively call after the page is built, and delaying the call before the page is built is also a method. Here is an elegant way to call:

    /// WidgetsBinding It can monitor the completion of the first frame drawing, and the completion of the first frame drawing indicates that the build has been completed . 
    WidgetsBinding . instance . addPostFrameCallback ( ( _ )  { 
      ///Get the focus of the input box 
      FocusScope . of ( context ) . requestFocus ( focusNode ) ; 
    } ) ;
  • 1
  • 2
  • 3
  • 4
  • 5
2.4 focusNode adds the acquisition and loss of focus
    
    ///Add a concurrent focusNode for gaining focus and losing focus . addListener ( ( ) { 
      ///Whether the current TextFeild has acquired the input focus 
      bool hasFocus = focusNode . hasFocus ; 
      ///Whether the current focusNode has added a concurrent 
      bool hasListeners = focusNode . hasListeners ;

      print("focusNode 兼听 hasFocus:$hasFocus  hasListeners:$hasListeners");
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

The effect diagram is as follows
insert image description here

3 TextFeild elegantly combines focusNode to achieve focus control

The source code is as follows:


import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

/// Organization 
///TextField focus acquisition control 
class  TextFeildHomePage3  extends  StatefulWidget  { 
  @override 
  State < StatefulWidget >  createState ( )  { 
    return  TextFeildHomePageState ( ) ; 
  } 
}

class TextFeildHomePageState extends State {
  
  ///Used to control the acquisition and closing of the focus of the TextField 
  FocusNode focusNode =  new  FocusNode ( ) ;

  @override
  void initState() {
    super.initState();
    
    
    ///Add a concurrent focusNode for gaining focus and losing focus . addListener ( ( ) { 
      ///Whether the current TextFeild has acquired the input focus 
      bool hasFocus = focusNode . hasFocus ; 
      ///Whether the current focusNode has added a concurrent 
      bool hasListeners = focusNode . hasListeners ;

      print("focusNode 兼听 hasFocus:$hasFocus  hasListeners:$hasListeners");
    });

    /// WidgetsBinding It can monitor the completion of the first frame drawing, and the completion of the first frame drawing indicates that the build has been completed . 
    WidgetsBinding . instance . addPostFrameCallback ( ( _ )  { 
      ///Get the focus of the input box 
      FocusScope . of ( context ) . requestFocus ( focusNode ) ; 
    } ) ; 
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("TextField 讲解"),
        actions: <Widget>[
          FlatButton(child: Text("获取"),onPressed: (){
            FocusScope.of(context).requestFocus ( focusNode ) ; 
          } , ) , 
          FlatButton ( child :  Text ( "lost" ) , onPressed :  ( ) { 
            focusNode . unfocus ( ) ; 
          } , ) , 
        ] , 
      ) , 
      body :  Container ( 
        ///SizedBox is used to limit A space 
        child :  SizedBox ( 
          width :  400 with a fixed width and height, 
          height :  100 , 
          child :  Container ( 
            color : Colors . white24 , 
            padding : EdgeInsets . all ( 10 ) , 
            ///Alignment is used to align Widget 
            alignment :  Alignment ( 0 ,  0 ) , 
            ///Text input box 
            child :  TextField ( 
// autofocus: true, 
            focusNode : focusNode, 
            ) , 
          ) , 
        ) , 
      ) , 
    ) ; 
  } 
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75

insert image description here

Tags: Focus control of Flutter text input box TextField

A full set of tutorials for Flutter project development focusNode TextField

Related: Focus control of Flutter text input box TextField