在Flutter中,我试图基于文本控制器动态更新我的列窗口小部件.我该怎么做呢? [英] In Flutter, I'm trying to dynamically update my column widget based on Text Controller. How do I do this?

查看:125
本文介绍了在Flutter中,我试图基于文本控制器动态更新我的列窗口小部件.我该怎么做呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要实现的目标是仅在文本控制器未经验证的情况下显示一条消息,否则显示一个空容器.如何根据文本控制器输出的内容重新绘制窗口小部件?

What I'm trying to achieve is showing a message only if the Text Controller is not validated, otherwise show an empty container. How do I go about redrawing the widget based on what the Text Controller is outputting?

想要的行为:

  • 当用户单击登录按钮时,flutter会检查用户名字段是否为空.
  • 如果为空,则在登录按钮下方显示消息.
  • 当用户再次单击文本字段并输入一个字符时,该消息消失并返回一个空容器.

代码:

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: TextFieldExample(),
        ),
      ),
    );
  }
}

class TextFieldExample extends StatefulWidget {
  @override
  _TextFieldExampleState createState() => _TextFieldExampleState();
}

class _TextFieldExampleState extends State<TextFieldExample> {
  @override
  void initState() {
    super.initState();
    _username.addListener(() {
      setState(() {});
    });
  }

  final _username = TextEditingController();
  bool hasMessage = false;
  String email = '';
  String validatorMessage;

  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.symmetric(vertical: 5),
      padding: EdgeInsets.symmetric(horizontal: 15),
      decoration: BoxDecoration(borderRadius: BorderRadius.circular(29)),
      child: Column(children: <Widget>[
        TextField(
          controller: _username,
          decoration:
              InputDecoration(icon: Icon(Icons.person), hintText: "Email"),
        ),
        Container(
            margin: EdgeInsets.symmetric(vertical: 5),
            child: ClipRRect(
                borderRadius: BorderRadius.circular(29),
                child: RaisedButton(
                    padding: EdgeInsets.symmetric(vertical: 10),
                    onPressed: () async {
                      if (_username.text.isNotEmpty) {
                        //do sign in
                      } else {
                        hasMessage = true;
                        validatorMessage = 'Check username or password';
                      }
                    },
                    child: Text("Login")))),
        //Change something here, in order to dynamically check and update
        if (hasMessage == false)
          Container()
        else
          Container(
              alignment: Alignment.center,
              child:
                  Text(validatorMessage, style: TextStyle(color: Colors.red))),
      ]),
    );
  }
}


 

推荐答案

要动态更改显示需要使用StreamBuilder的文本的小部件,该小部件将为每个新事件重新生成:

To change dynamically the widget showing the text you need to use StreamBuilder, that rebuilds for every new event:

String validatorMessage;
bool validate = false;     //will be true if the user clicked in the login button
final _usernameController = StreamController<String>(); //stream to validate the text

Widget build(BuildContext context) {
  return Scaffold(
    body: Container(
      margin: EdgeInsets.symmetric(vertical: 5),
      padding: EdgeInsets.symmetric(horizontal: 15),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(29),
      ),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          TextField(
            onChanged: _usernameController.add, //everytime the text changes a new value will be added to the stream
            decoration: InputDecoration(
              icon: Icon(Icons.person),
              hintText: "Email",
            ),
          ),
          Container(
            margin: EdgeInsets.symmetric(vertical: 5),
            child: ClipRRect(
              borderRadius: BorderRadius.circular(29),
              child: RaisedButton(
                padding: EdgeInsets.symmetric(vertical: 10),
                onPressed: () {
                  setState(() {
                    validate = true; 
                  });
                },
                child: Text("Login"),
              ),
            ),
          ),
          StreamBuilder<String>(
            initialData: '',
            stream: _usernameController.stream,
            builder: (context, snapshot) {
              if (snapshot.data.isEmpty && validate == true) { //checking the stream and if the user clicked in the button
                return Container(
                  alignment: Alignment.center,
                  child: Text(
                    'Check your e-mail and password.',
                    style: TextStyle(
                      color: Colors.red,
                    ),
                  ),
                );
              } else {
                return Container();
              }
            },
          ),
        ],
      ),
    ),
  );
}

@override
void dispose() {
  _usernameController.close();
  super.dispose();
}

这篇关于在Flutter中,我试图基于文本控制器动态更新我的列窗口小部件.我该怎么做呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆