2

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
  • 1,005
  • 11
  • 30

1 Answers1

1

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,
        ),
      ),
    );
  }
}
chunhunghan
  • 51,087
  • 5
  • 102
  • 120
  • Thanks very much!!! @chunhunghan, may be you can help me with this too.. https://stackoverflow.com/questions/64870128/flutter-how-to-show-today-tommorow-after-comparing-the-date-in-db-with-presen – Jagadish Nov 17 '20 at 12:49