显示文本字段对话框而不被键盘覆盖? [英] Show a text field dialog without being covered by keyboard?

查看:89
本文介绍了显示文本字段对话框而不被键盘覆盖?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个 SimpleDialog ,允许用户输入其名称。但是在显示该对话框时,该对话框被屏幕上的键盘隐藏了一半:





如何使对话框完全可见?



编辑:我觉得很奇怪主页小部件(FocusVisibilityDemo)识别出减小的高度,因此调整推我按钮的位置以保持在中心。不幸的是,对话框的行为方式不同。



这是我的代码:

  import'package:flutter / material.dart'; 

类FocusVisibilityDemo扩展了StatefulWidget {
@override
_FocusVisibilityDemoState createState()=>新的_FocusVisibilityDemoState();
}

类_FocusVisibilityDemoState扩展了State< FocusVisibilityDemo> {
@override
Widget build(BuildContext context){
return new Scaffold(
appBar:new AppBar(title:new Text('Text Dialog Demo')),
正文:new Center(
子项:new RaisedButton(
onPressed:_showDialog,
子项:new Text( Push Me),
),
) ,
);
}

_showDialog()异步{
等待showDialog< String>(
context:context,context,
child:new AlertDialog(
contentPadding :const EdgeInsets.all(16.0),
内容:new Row(
子级:< Widget> [
new Expanded(
子级:new TextField(
autofocus :true,
装饰:new InputDecoration(
labelText:'Full Name',hintText:'eg。John Smith'),
),

],
),
操作:< Widget> [
new FlatButton(
child:const Text('CANCEL'),
onPressed:(){
Navigator.pop(context);
}),
new FlatButton(
child:const Text('OPEN'),
onPressed:(){
Navigator .pop(context);
})
],
),
);
}
}

void main(){
runApp(new MaterialApp(home:new FocusVisibilityDemo()));
}


解决方案

如果您的用例是在对话框内添加多个 TextFields ,以便您的主 Form 起作用不拥挤,我认为最好构建比 AlertDialog SimpleDialog 更可定制的内容简单的活动(确认,广播等)。



否则,为什么要使用 Dialog 单个 TextField 吗?



当我们添加多个 TextField 时s我们应该谨慎选择设计,因为其他人将与该视图交互以填充数据,在这种情况下,我更喜欢使用

  import'package:flutter / material.dart'; 

void main(){
runApp(new MaterialApp(home:new FocusVisibilityDemo()));
}

类FocusVisibilityDemo扩展了StatefulWidget {
@override
_FocusVisibilityDemoState createState()=>新的_FocusVisibilityDemoState();
}


类_FocusVisibilityDemoState扩展State< FocusVisibilityDemo> {
@override
Widget build(BuildContext context){
return new Scaffold(
appBar:new AppBar(title:new Text('Text Dialog Demo')),
正文:new Center(
子项:new RaisedButton(
onPressed:_showDialog,
子项:new Text( Push Me),
),
) ,
);
}

_showDialog()异步{
等待showDialog< String>(
context:context,
child:new _SystemPadding(child:new AlertDialog(
contentPadding:const EdgeInsets.all(16.0),
内容:new Row(
child:< Widget> [
new Expanded(
child:new TextField(
自动对焦:true,
装饰:new InputDecoration(
labelText:'Full Name',hintText:'eg。John Smith'),
),

],
),
操作:< Widget> [
new FlatButton(
child:const Text('CANCEL'),
onPressed:( ){
Navigator.pop(context);
}),
个新的FlatButton(
子级:const Text('OPEN'),
onPressed:(){
Navigator.pop(上下文);
})
],
),),
);
}
}


类_SystemPadding扩展了StatelessWidget {
final Widget child;

_SystemPadding({Key key,this.child}):super(key:key);

@override
小部件构建(BuildContext上下文){
var mediaQuery = MediaQuery.of(context);
返回新的AnimatedContainer(
padding:mediaQuery.viewInsets,
持续时间:const Duration(毫秒:300),
child:child);
}
}


I'm trying to create a SimpleDialog that allows the user to enter their name. But when it is displayed the dialog is half hidden by the on-screen keyboard:

How can I get the Dialog to be fully visible?

Edit: I find it strange that the homepage widget (FocusVisibilityDemo) recognises the reduced height and therefore adjusts the position of the 'Push Me' button to remain in the center. Unfortunately the dialog doesn't behave the same way.

Here is my code:

import 'package:flutter/material.dart';

class FocusVisibilityDemo extends StatefulWidget {
  @override
  _FocusVisibilityDemoState createState() => new _FocusVisibilityDemoState();
}

class _FocusVisibilityDemoState extends State<FocusVisibilityDemo> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text('Text Dialog Demo')),
      body: new Center(
        child: new RaisedButton(
          onPressed: _showDialog,
          child: new Text("Push Me"),
        ),
      ),
    );
  }

  _showDialog() async {
    await showDialog<String>(
      context: context,
      child: new AlertDialog(
        contentPadding: const EdgeInsets.all(16.0),
        content: new Row(
          children: <Widget>[
            new Expanded(
              child: new TextField(
                autofocus: true,
                decoration: new InputDecoration(
                    labelText: 'Full Name', hintText: 'eg. John Smith'),
              ),
            )
          ],
        ),
        actions: <Widget>[
          new FlatButton(
              child: const Text('CANCEL'),
              onPressed: () {
                Navigator.pop(context);
              }),
          new FlatButton(
              child: const Text('OPEN'),
              onPressed: () {
                Navigator.pop(context);
              })
        ],
      ),
    );
  }
}

void main() {
  runApp(new MaterialApp(home: new FocusVisibilityDemo()));
}

解决方案

If your use case is to add multiple TextFields inside your Dialog so your main Form does not get crowded, I think it is better if you build something more customizable than AlertDialog and SimpleDialog as they are used for simple activities (confirmations, radios..etc).

Otherwise, why do you want to use a Dialog for a single TextField ?

When we add multiple TextFields we should be careful about our design choices since other people will interact with this view to fill in the data, in this case I prefer to use fullscreenDialog property of PageRoute class. I am not sure if SimpleDialog can be suitable for that in Flutter.

Here is a quick example on how to use a FullScreenDialog, I hope this help and you should be able to modify it the way you want:

import 'package:flutter/material.dart';


void main() {
  runApp(new MaterialApp(home: new MyApp(),));
}

class MyApp extends StatefulWidget {
  @override
  MyAppState createState() => new MyAppState();
}

class MyAppState extends State<MyApp> {
  FullScreenDialog _myDialog = new FullScreenDialog();

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Fill this form"),
        ),
        body: new Column(
          children: <Widget>[
            new TextField(controller: new TextEditingController(
                text: "Add a single text field"),),

            new Card(child: new ListTile(
              title: new Text("Click to add your top 3 amazing skills"),
              subtitle: new Text(
                  "${_myDialog._skillOne} ${_myDialog._skillTwo} ${_myDialog
                      ._skillThree}"),
              onTap: () {
                Navigator.push(context, new MaterialPageRoute(
                  builder: (BuildContext context) => _myDialog,
                  fullscreenDialog: true,
                ));
              },
            ),
            ),
          ],
        )
    );
  }

}


class FullScreenDialog extends StatefulWidget {
  String _skillOne = "You have";
  String _skillTwo = "not Added";
  String _skillThree = "any skills yet";

  @override
  FullScreenDialogState createState() => new FullScreenDialogState();
}

class FullScreenDialogState extends State<FullScreenDialog> {
  TextEditingController _skillOneController = new TextEditingController();
  TextEditingController _skillTwoController = new TextEditingController();

  TextEditingController _skillThreeController = new TextEditingController();

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Add your top 3 skills"),
        ),
        body: new Padding(child: new ListView(
          children: <Widget>[
            new TextField(controller: _skillOneController,),
            new TextField(controller: _skillTwoController,),
            new TextField(controller: _skillThreeController,),
            new Row(
              children: <Widget>[
                new Expanded(child: new RaisedButton(onPressed: () {
                  widget._skillThree = _skillThreeController.text;
                  widget._skillTwo = _skillTwoController.text;
                  widget._skillOne = _skillOneController.text;
                  Navigator.pop(context);
                }, child: new Text("Save"),))
              ],
            )
          ],
        ), padding: const EdgeInsets.symmetric(horizontal: 20.0),)
    );
  }


}

EDIT

After doing some research, it seems that this is a bug in the current Flutter version, the temporary fix is also documented in this issue.

import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(home: new FocusVisibilityDemo()));
}

class FocusVisibilityDemo extends StatefulWidget {
  @override
  _FocusVisibilityDemoState createState() => new _FocusVisibilityDemoState();
}


class _FocusVisibilityDemoState extends State<FocusVisibilityDemo> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text('Text Dialog Demo')),
      body: new Center(
        child: new RaisedButton(
          onPressed: _showDialog,
          child: new Text("Push Me"),
        ),
      ),
    );
  }

  _showDialog() async {
    await showDialog<String>(
      context: context,
      child: new _SystemPadding(child: new AlertDialog(
        contentPadding: const EdgeInsets.all(16.0),
        content: new Row(
          children: <Widget>[
            new Expanded(
              child: new TextField(
                autofocus: true,
                decoration: new InputDecoration(
                    labelText: 'Full Name', hintText: 'eg. John Smith'),
              ),
            )
          ],
        ),
        actions: <Widget>[
          new FlatButton(
              child: const Text('CANCEL'),
              onPressed: () {
                Navigator.pop(context);
              }),
          new FlatButton(
              child: const Text('OPEN'),
              onPressed: () {
                Navigator.pop(context);
              })
        ],
      ),),
    );
  }
}


class _SystemPadding extends StatelessWidget {
  final Widget child;

  _SystemPadding({Key key, this.child}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    var mediaQuery = MediaQuery.of(context);
    return new AnimatedContainer(
        padding: mediaQuery.viewInsets,
        duration: const Duration(milliseconds: 300),
        child: child);
  }
}

这篇关于显示文本字段对话框而不被键盘覆盖?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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