【问题标题】:How to make TextField's label wont move when out of focus in Flutter如何使文本字段标签在 Flutter 中失焦时不会移动
【发布时间】:2021-12-29 08:49:42
【问题描述】:

我是 Flutter 新手。

我正在尝试复制以下 UI,它有多个 TextField,当我单击其他 TextField 时,它们的所有标签都不会最大化,它们会保持焦点以显示其中的内容:https://i.stack.imgur.com/8lUeV.png

我制作的 UI:https://i.stack.imgur.com/o9Rpj.png

我尝试了 autofocus: on 但它不起作用,因为它一次只适用于一个 TextField。

我的代码:

import 'dart:core';
import 'package:flutter/material.dart';
import 'package:login_sample/models/user.dart';

class EmployeeProfile extends StatefulWidget {
  const EmployeeProfile({Key? key, required this.user}) : super(key: key);

  final User user;

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

class _EmployeeProfileState extends State<EmployeeProfile> {

  late String name = '';
  late String email = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          Container(
              decoration: const BoxDecoration(
                  gradient: LinearGradient(
                      begin: Alignment.centerLeft,
                      end: Alignment.bottomCenter,
                      colors: [Colors.blue, Colors.blue])),
              height: MediaQuery.of(context).size.height * 0.3
          ),
          Card(
              elevation: 20.0,
              shape: const RoundedRectangleBorder(
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(50),
                  topRight: Radius.circular(50),
                ),
              ),
              margin: const EdgeInsets.only(left: 0.0, right: 0.0, top: 100.0),
              child: ListView(
                children: <Widget>[
                  SizedBox(
                    child: TextField(
                      autofocus: true,
                      onChanged: (val){
                        name = val;
                      },
                      decoration: InputDecoration(
                        contentPadding: const EdgeInsets.all(10.0),
                        labelText: 'Employee Name',
                        hintText: widget.user.name,
                        labelStyle: const TextStyle(
                          color: Color.fromARGB(255, 107, 106, 144),
                          fontSize: 14,
                          fontWeight: FontWeight.w500,
                        ),
                        border: OutlineInputBorder(
                          borderSide: const BorderSide(color: Color.fromARGB(255, 107, 106, 144), width: 2),
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                    ),
                    width: 150.0,
                  ),
                  SizedBox(
                    child: TextField(
                      autofocus: true,
                      onChanged: (val){
                        email = val;
                      },
                      decoration: InputDecoration(
                        contentPadding: const EdgeInsets.all(10.0),
                        labelText: 'Employee Email',
                        hintText: widget.user.email,
                        labelStyle: const TextStyle(
                          color: Color.fromARGB(255, 107, 106, 144),
                          fontSize: 14,
                          fontWeight: FontWeight.w500,
                        ),
                        border: OutlineInputBorder(
                          borderSide: const BorderSide(color: Color.fromARGB(255, 107, 106, 144), width: 2),
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                    ),
                    width: 150.0,
                  ),
                  TextButton(
                      onPressed: (){
                        print(widget.user.name);
                        print(widget.user.email);
                        setState(() {
                          widget.user.name = name;
                          widget.user.email = email;
                        });
                      },
                      child: const Text('Save'),
                  ),
                ],
              )
          ),
          Positioned(
            top: 0.0,
            left: 0.0,
            right: 0.0,
            child: AppBar(// Add AppBar here only
              backgroundColor: Colors.transparent,
              elevation: 0.0,
              title: Text(
                widget.user.name.toString(),
                style: const TextStyle(
                  letterSpacing: 0.0,
                  fontSize: 20.0,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

P/s: sr im 不是很擅长英语来正确描述它

【问题讨论】:

  • 您希望标签始终可见吗?
  • 是的,我希望标签始终在边框上,即使我与其他 TextField 交互,它也不会从边框向下移动。
  • 如果TextField 是空的并且您没有关注它,标签将被隐藏而hint 将可见。你在TextField 上看到的是hint,而不是向下移动label

标签: flutter flutter-layout


【解决方案1】:

如果您关注TextFieldTextField 的内容,标签将可见。如果您的意思是保持标签始终可见,您可以在InputDecoration 上添加floatingLabelBehavior: FloatingLabelBehavior.always

import 'dart:core';
import 'package:flutter/material.dart';
import 'package:login_sample/models/user.dart';

class EmployeeProfile extends StatefulWidget {
  const EmployeeProfile({Key? key, required this.user}) : super(key: key);

  final User user;

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

class _EmployeeProfileState extends State<EmployeeProfile> {

  late String name = '';
  late String email = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          Container(
              decoration: const BoxDecoration(
                  gradient: LinearGradient(
                      begin: Alignment.centerLeft,
                      end: Alignment.bottomCenter,
                      colors: [Colors.blue, Colors.blue])),
              height: MediaQuery.of(context).size.height * 0.3
          ),
          Card(
              elevation: 20.0,
              shape: const RoundedRectangleBorder(
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(50),
                  topRight: Radius.circular(50),
                ),
              ),
              margin: const EdgeInsets.only(left: 0.0, right: 0.0, top: 100.0),
              child: ListView(
                children: <Widget>[
                  SizedBox(
                    child: TextField(
                      autofocus: true,
                      onChanged: (val){
                        name = val;
                      },
                      decoration: InputDecoration(
                        contentPadding: const EdgeInsets.all(10.0),
                        labelText: 'Employee Name',
                        hintText: widget.user.name,
                        // add here
                        floatingLabelBehavior: FloatingLabelBehavior.always 
                        labelStyle: const TextStyle(
                          color: Color.fromARGB(255, 107, 106, 144),
                          fontSize: 14,
                          fontWeight: FontWeight.w500,
                        ),
                        border: OutlineInputBorder(
                          borderSide: const BorderSide(color: Color.fromARGB(255, 107, 106, 144), width: 2),
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                    ),
                    width: 150.0,
                  ),
                  SizedBox(
                    child: TextField(
                      autofocus: true,
                      onChanged: (val){
                        email = val;
                      },
                      decoration: InputDecoration(
                        contentPadding: const EdgeInsets.all(10.0),
                        labelText: 'Employee Email',
                        hintText: widget.user.email,
                        // add here
                        floatingLabelBehavior: FloatingLabelBehavior.always
                        labelStyle: const TextStyle(
                          color: Color.fromARGB(255, 107, 106, 144),
                          fontSize: 14,
                          fontWeight: FontWeight.w500,
                        ),
                        border: OutlineInputBorder(
                          borderSide: const BorderSide(color: Color.fromARGB(255, 107, 106, 144), width: 2),
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                    ),
                    width: 150.0,
                  ),
                  TextButton(
                      onPressed: (){
                        print(widget.user.name);
                        print(widget.user.email);
                        setState(() {
                          widget.user.name = name;
                          widget.user.email = email;
                        });
                      },
                      child: const Text('Save'),
                  ),
                ],
              )
          ),
          Positioned(
            top: 0.0,
            left: 0.0,
            right: 0.0,
            child: AppBar(// Add AppBar here only
              backgroundColor: Colors.transparent,
              elevation: 0.0,
              title: Text(
                widget.user.name.toString(),
                style: const TextStyle(
                  letterSpacing: 0.0,
                  fontSize: 20.0,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

【讨论】:

    【解决方案2】:

    试试下面的代码希望它对你有帮助。在 Padding 中添加您的 ListView()

        Padding(
              padding: EdgeInsets.all(20),
              child: ListView(
                children: <Widget>[
                  SizedBox(
                    child: TextField(
                      autofocus: true,
                      onChanged: (val) {},
                      decoration: InputDecoration(
                        contentPadding: const EdgeInsets.all(10.0),
                        labelText: 'Employee Name',
                        hintText: 'widget.user.name',
                        labelStyle: const TextStyle(
                          color: Color.fromARGB(255, 107, 106, 144),
                          fontSize: 14,
                          fontWeight: FontWeight.w500,
                        ),
                        border: OutlineInputBorder(
                          borderSide: const BorderSide(
                              color: Color.fromARGB(255, 107, 106, 144),
                              width: 2),
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                    ),
                    width: 150.0,
                  ),
                  SizedBox(
                    height: 20,
                  ),
                  SizedBox(
                    child: TextField(
                      autofocus: true,
                      onChanged: (val) {},
                      decoration: InputDecoration(
                        contentPadding: const EdgeInsets.all(10.0),
                        labelText: 'Employee Email',
                        hintText: 'widget.user.email',
                        labelStyle: const TextStyle(
                          color: Color.fromARGB(255, 107, 106, 144),
                          fontSize: 14,
                          fontWeight: FontWeight.w500,
                        ),
                        border: OutlineInputBorder(
                          borderSide: const BorderSide(
                              color: Color.fromARGB(255, 107, 106, 144),
                              width: 2),
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                    ),
                    width: 150.0,
                  ),
                  TextButton(
                    onPressed: () {},
                    child: const Text('Save'),
                  ),
                ],
              ),
            ),
    

    你的屏幕->

    【讨论】:

    • 非常感谢,感谢您的帮助,但我希望两个 TextField 看起来像这样 ibb.co/DM4jsNW,当其中一个聚焦时,内容不会隐藏在 labelText 后面。如果图片中的不是TextField,对不起,如果我错了
    • @Kronkdark 如果我的回答解决了您的问题,请标记(打勾)谢谢
    猜你喜欢
    • 1970-01-01
    • 2020-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-14
    • 2021-07-12
    • 2022-06-27
    • 2011-09-11
    相关资源
    最近更新 更多