Flutter - Change text input type and input formatters dynamically on tap

1,720

You can copy paste run full code below
You can use ValueListenableBuilder and ValueNotifier
You also need FocusNode to control keyboard
You can see working demo below
code snippet

final ValueNotifier<bool> joinlinkname = ValueNotifier<bool>(false);
...
joinchanged() async {
    FocusManager.instance.primaryFocus.unfocus();
    joinlinkname.value = !joinlinkname.value;
    await Future.delayed(Duration(milliseconds: 500), () {});
    myFocusNode.requestFocus();
  }
...  
ValueListenableBuilder(
          builder: (BuildContext context, bool value, Widget child) {
            return Column(
              children: [
                GestureDetector(
                  onTap: () {
                    joinchanged();
                  },
                  child: Text(
                    joinlinkname.value ? 'number' : 'text',
                    style: TextStyle(
                      color: Colors.blue,
                      fontSize: 12,
                    ),
                  ),
                ),
                TextField(
                  focusNode: myFocusNode,
                  keyboardType: joinlinkname.value
                      ? TextInputType.phone  

working demo

enter image description here

full code

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final ValueNotifier<bool> joinlinkname = ValueNotifier<bool>(false);
  FocusNode myFocusNode;

  @override
  void initState() {
    super.initState();
    myFocusNode = FocusNode();
  }

  @override
  void dispose() {
    myFocusNode.dispose();
    super.dispose();
  }

  joinchanged() async {
    FocusManager.instance.primaryFocus.unfocus();
    joinlinkname.value = !joinlinkname.value;
    await Future.delayed(Duration(milliseconds: 500), () {});
    myFocusNode.requestFocus();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.title)),
      body: Center(
        child: ValueListenableBuilder(
          builder: (BuildContext context, bool value, Widget child) {
            return Column(
              children: [
                GestureDetector(
                  onTap: () {
                    joinchanged();
                  },
                  child: Text(
                    joinlinkname.value ? 'number' : 'text',
                    style: TextStyle(
                      color: Colors.blue,
                      fontSize: 12,
                    ),
                  ),
                ),
                TextField(
                  focusNode: myFocusNode,
                  keyboardType: joinlinkname.value
                      ? TextInputType.phone
                      : TextInputType.text,
                  decoration: InputDecoration(
                    labelText: joinlinkname.value ? 'num' : "text",
                  ),
                  inputFormatters: [
                    joinlinkname.value
                        ? FilteringTextInputFormatter.allow(RegExp('[0-9]'))
                        : FilteringTextInputFormatter.allow(RegExp('[azAZ09]')),
                  ],
                ),
              ],
            );
          },
          valueListenable: joinlinkname,
        ),
      ),
    );
  }
}
Share:
1,720
Jagadish
Author by

Jagadish

I develop cross-platform apps and websites. I have developed 3 android apps and published them on the Play Store, one of them is Just Meet with thousands of daily users. I have been coding from class 8 and have gained 3 years of experience with flutter language and android app development. I am a student of class 10 presently, I study all day and code at night. I believe in developing free or low-cost high-quality premium apps available to all the people of India. Recently I developed Just Meet, a video conferencing app that gives complete privacy, is secured and end to end encrypted, uses lesser data and battery, and works well in bad network areas like a charm and the best thing is it has no restriction on the number of participants or meeting duration and that too completely free! As I code alone it took me about 3 months to complete the initial release of it. It has a lot of features, some are new and very helpful. I believe this app will help a lot of people save their money and continue their meetings even in the worst network peacefully without having the tension of their user data! I have experience working on Firebase, Adsense, Admob, Facebook Audience Network, Unity Ads, etc, and also little in Python, Java, JavaScript, HTML, CSS, AIML. When am not studying and frustrated with bugs and errors usually spend my time working out on my muscles, painting, and playing with my pet dog "Ani".

Updated on November 27, 2022

Comments

  • Jagadish
    Jagadish over 1 year

    I want to change the text input type and input formatters of a text field dynamically on tap. But the problem is once the text input type is done it is not changed on tap whereas the label text acts as expected.

    I have done like below

    bool joinlinkname = false;
    joinchanged() {
      if (joinlinkname == false) {
        setState(() {
          joinlinkname = true;
        });
      } else {
        setState(() {
        joinlinkname = false;
        });
      }
    } 
    
    TextField(
      keyboardType: joinlinkname? TextInputType.text : TextInputType.phone,
      labelText: joinlinkname ? 'num' : "text",
      inputFormatters: [joinlinkname ? 
        FilteringTextInputFormatter.allow(RegExp('[azAZ09]')):FilteringTextInputFormatter.allow(RegExp('[0-9]')),
      ],
    ),
    
    GestureDetector(
      onTap: () {
        joinchanged();
      },
      child: Text(joinlinkname ? 'number' : 'text',
                  style: TextStyle(
                  color: Colors.blue,
                  fontSize: 12,
                  ),
             ),
     ),
    

    Please can anyone tell how to do it?

    • Jagadish
      Jagadish over 3 years
      Thanks to all in advance!!!
  • Jagadish
    Jagadish over 3 years
    Thanks very much!!! @chunhunghan, may be you can help me with this too.. stackoverflow.com/questions/64870128/…