首页 > 解决方案 > Flutter - 点击时动态更改文本输入类型和输入格式化程序

问题描述

我想在 tap 上动态更改文本输入类型和文本字段的输入格式化程序。但问题是一旦文本输入类型完成,它不会在点击时更改,而标签文本按预期运行

我做了如下

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,
              ),
         ),
 ),

请任何人都可以告诉如何做到这一点?

标签: flutterdartdynamictextfieldinputformatter

解决方案


您可以在下面复制粘贴运行完整代码
您可以使用ValueListenableBuilder并且ValueNotifier
您还需要FocusNode控制键盘您可以在 代码片段
下面看到工作演示

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  

工作演示

在此处输入图像描述

完整代码

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,
        ),
      ),
    );
  }
}

推荐阅读