Flutter 带SnackBar的底部文本字段

Flutter 带SnackBar的底部文本字段,flutter,flutter-layout,flutter-animation,Flutter,Flutter Layout,Flutter Animation,我想在页面底部创建一个类似消息应用程序的文本字段 还有一个IconButton,如果TextField不为空,它会将输入的文本添加到ListView。如果为空,则会在SnackBar中显示错误 问题在于TextField顶部的SnackBar堆栈。但我希望它是TextField的顶部或底部 import 'package:flutter/material.dart'; Future<void> main() async { runApp(MyApp()); } class M

我想在页面底部创建一个类似消息应用程序的
文本字段

还有一个
IconButton
,如果
TextField
不为空,它会将输入的文本添加到
ListView
。如果为空,则会在
SnackBar
中显示错误

问题在于
TextField
顶部的
SnackBar
堆栈。但我希望它是
TextField
的顶部或底部

import 'package:flutter/material.dart';

Future<void> main() async {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MainPage(),
    );
  }
}

class MainPage extends StatefulWidget {
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  final _textList = <String>[];

  TextEditingController _textController;

  bool _addText(context, String text) {
    print(text);
    if (text?.isNotEmpty == true) {
      setState(() {
        _textList.add(text);
      });
      return true;
    } else {
      Scaffold.of(context).showSnackBar(
        SnackBar(
          content: Text("Invalid Text Entered"),
          behavior: SnackBarBehavior.fixed,
        ),
      );
      return false;
    }
  }

  @override
  void initState() {
    _textController = TextEditingController();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Demo"),
      ),
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Expanded(
              child: ListView.separated(
                itemCount: _textList.length,
                separatorBuilder: (_, __) => Divider(height: 1.0),
                itemBuilder: (context, index) => ListTile(
                  title: Text("${_textList[index]}"),
                ),
              ),
            ),
            _buildBottom(),
          ],
        ),
      ),
    );
  }

  Widget _buildBottom() {
    return Material(
      elevation: 5.0,
      color: Colors.blue[100],
      child: Row(
        children: <Widget>[
          Expanded(
            child: TextField(
              controller: _textController,
              decoration: InputDecoration(
                hintText: "Enter Text",
                contentPadding: EdgeInsets.symmetric(horizontal: 10.0),
                border: InputBorder.none,
              ),
            ),
          ),
          Builder(
            builder: (context) => IconButton(
              icon: Icon(Icons.add),
              onPressed: () {
                final success = _addText(context, _textController.text);
                if (success) _textController.clear();
              },
            ),
          ),
        ],
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
Future main()异步{
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
主页:主页(),
);
}
}
类MainPage扩展了StatefulWidget{
@凌驾
_MainPageState createState()=>\u MainPageState();
}
类_MainPageState扩展状态{
最终文本列表=[];
TextEditingController\u textController;
bool\u addText(上下文、字符串文本){
印刷品(文本);
if(text?.isNotEmpty==true){
设置状态(){
_textList.add(文本);
});
返回true;
}否则{
Scaffold.of(上下文).showSnackBar(
小吃条(
内容:文本(“输入的无效文本”),
行为:SnackBarBehavior.fixed,
),
);
返回false;
}
}
@凌驾
void initState(){
_textController=TextEditingController();
super.initState();
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(“演示”),
),
正文:安全区(
子:列(
儿童:[
扩大(
子项:ListView.separated(
itemCount:_textList.length,
分离器构建器:(,_)=>分离器(高度:1.0),
itemBuilder:(上下文,索引)=>ListTile(
标题:文本(${u textList[index]}),
),
),
),
_buildBottom(),
],
),
),
);
}
小部件_buildBottom(){
退货(
标高:5.0,
颜色:颜色。蓝色[100],
孩子:排(
儿童:[
扩大(
孩子:TextField(
控制器:_textController,
装饰:输入装饰(
hintText:“输入文本”,
内容填充:边集。对称(水平:10.0),
边框:InputBorder.none,
),
),
),
建筑商(
生成器:(上下文)=>IconButton(
图标:图标(Icons.add),
已按下:(){
最终成功=_addText(上下文,_textController.text);
if(成功)_textController.clear();
},
),
),
],
),
);
}
}

这是我在

中的代码,也许使用
Flushbar
可以帮助解决您的问题。有许多属性可以更改,例如
flushbarPosition

它可能无法准确地解决您的问题,但它可以使刷新条从顶部而不是底部显示,这是解决问题的一种方法


Flushbar

也许使用
Flushbar
可以帮助解决您的问题。有许多属性可以更改,例如
flushbarPosition

它可能无法准确地解决您的问题,但它可以使刷新条从顶部而不是底部显示,这是解决问题的一种方法

Flushbar

试试这个

import 'package:flutter/material.dart';

Future<void> main() async {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MainPage(),
    );
  }
}

class MainPage extends StatefulWidget {
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  final _textList = <String>[];

  TextEditingController _textController;

  bool isVisible = false;

  bool _addText(context, String text) {
    print(text);
    if (text?.isNotEmpty == true) {
      setState(() {
        _textList.add(text);
      });
      return true;
    } else {
      Scaffold.of(context).showSnackBar(
        new SnackBar(
          content: Text("Invalid Text Entered"),
          behavior: SnackBarBehavior.fixed,
          duration: Duration(seconds: 3),
          onVisible: (() {
            setState(() {
              isVisible = true;
            });
            Future.delayed(Duration(seconds: 3)).then((_) => setState(() {
                  isVisible = false;
                }));
          }),
        ),
      );
      return false;
    }
  }

  @override
  void initState() {
    _textController = TextEditingController();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Demo"),
      ),
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Expanded(
              child: ListView.separated(
                itemCount: _textList.length,
                separatorBuilder: (_, __) => Divider(height: 1.0),
                itemBuilder: (context, index) => ListTile(
                  title: Text("${_textList[index]}"),
                ),
              ),
            ),
            AnimatedContainer(
              margin: EdgeInsets.only(bottom: isVisible ? 50 : 0),
              child: _buildBottom(),
              duration: Duration(milliseconds: 100),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildBottom() {
    return Material(
      elevation: 5.0,
      color: Colors.blue[100],
      child: Row(
        children: <Widget>[
          Expanded(
            child: TextField(
              controller: _textController,
              decoration: InputDecoration(
                hintText: "Enter Text",
                contentPadding: EdgeInsets.symmetric(horizontal: 10.0),
                border: InputBorder.none,
              ),
            ),
          ),
          Builder(
            builder: (context) => IconButton(
              icon: Icon(Icons.add),
              onPressed: () {
                final success = _addText(context, _textController.text);
                if (success) _textController.clear();
              },
            ),
          ),
        ],
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
Future main()异步{
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
主页:主页(),
);
}
}
类MainPage扩展了StatefulWidget{
@凌驾
_MainPageState createState()=>\u MainPageState();
}
类_MainPageState扩展状态{
最终文本列表=[];
TextEditingController\u textController;
bool isVisible=false;
bool\u addText(上下文、字符串文本){
印刷品(文本);
if(text?.isNotEmpty==true){
设置状态(){
_textList.add(文本);
});
返回true;
}否则{
Scaffold.of(上下文).showSnackBar(
新小吃吧(
内容:文本(“输入的无效文本”),
行为:SnackBarBehavior.fixed,
持续时间:持续时间(秒数:3),
onVisible:(){
设置状态(){
isVisible=true;
});
Future.delayed(持续时间(秒:3))。然后(())=>setState(){
isVisible=false;
}));
}),
),
);
返回false;
}
}
@凌驾
void initState(){
_textController=TextEditingController();
super.initState();
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(“演示”),
),
正文:安全区(
子:列(
儿童:[
扩大(
子项:ListView.separated(
itemCount:_textList.length,
分离器构建器:(,_)=>分离器(高度:1.0),
itemBuilder:(上下文,索引)=>ListTile(
标题:文本(${u textList[index]}),
),
),
),
动画容器(
边距:仅限边集(底部:可见?50:0),
子项:_buildBottom(),
持续时间:持续时间(毫秒:100),
),
],
),
),
);
}
小部件_buildBottom(){
退货(
标高:5.0,
颜色:颜色。蓝色[100],
孩子:排(
儿童:[
扩大(
孩子:TextField(
控制器:_textController,
装饰:输入装饰(
hintText:“输入文本