Dart 当我选择一个文本字段时,键盘会在其上移动
当我选择一个文本字段时,将显示键盘,但键盘会隐藏我选择的文本字段。有人有解决方案吗?当文本字段获得焦点时,制作动画并向上移动文本字段容器 有关合成动画的学习,请参阅: 使用Flatter的FocusNode检测文本字段上的焦点 编辑: 在这里,我写了一个例子,完全符合您的要求:Dart 当我选择一个文本字段时,键盘会在其上移动,dart,flutter,Dart,Flutter,当我选择一个文本字段时,将显示键盘,但键盘会隐藏我选择的文本字段。有人有解决方案吗?当文本字段获得焦点时,制作动画并向上移动文本字段容器 有关合成动画的学习,请参阅: 使用Flatter的FocusNode检测文本字段上的焦点 编辑: 在这里,我写了一个例子,完全符合您的要求: import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends Stateles
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Animation Demo',
theme: new ThemeData(
primaryColor: new Color(0xFFFF0000),
),
home: new FormDemo(),
);
}
}
class FormDemo extends StatefulWidget {
@override
_FormDemoState createState() => _FormDemoState();
}
class _FormDemoState extends State<FormDemo> with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation _animation;
FocusNode _focusNode = FocusNode();
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: Duration(milliseconds: 300));
_animation = Tween(begin: 300.0, end: 50.0).animate(_controller)
..addListener(() {
setState(() {});
});
_focusNode.addListener(() {
if (_focusNode.hasFocus) {
_controller.forward();
} else {
_controller.reverse();
}
});
}
@override
void dispose() {
_controller.dispose();
_focusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false, // this avoids the overflow error
appBar: AppBar(
title: Text('TextField Animation Demo'),
),
body: new InkWell( // to dismiss the keyboard when the user tabs out of the TextField
splashColor: Colors.transparent,
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Container(
padding: const EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
SizedBox(height: _animation.value),
TextFormField(
decoration: InputDecoration(
labelText: 'I move!',
),
focusNode: _focusNode,
)
],
),
),
),
);
}
}
导入“包装:颤振/材料.省道”;
void main()=>runApp(新的MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回新材料PP(
debugShowCheckedModeBanner:false,
标题:“动画演示”,
主题:新主题数据(
primaryColor:新颜色(0xFFFF0000),
),
主页:新FormDemo(),
);
}
}
类FormDemo扩展了StatefulWidget{
@凌驾
_FormDemoState createState();
}
类_FormDemoState使用SingleTickerProviderStateMixin扩展状态{
动画控制器_控制器;
动画(动画),;
FocusNode_FocusNode=FocusNode();
@凌驾
void initState(){
super.initState();
_controller=AnimationController(vsync:this,duration:duration(毫秒:300));
_动画=Tween(开始:300.0,结束:50.0)。动画(\u控制器)
…addListener(){
setState((){});
});
_focusNode.addListener(){
if(_focusNode.hasFocus){
_controller.forward();
}否则{
_controller.reverse();
}
});
}
@凌驾
无效处置(){
_controller.dispose();
_focusNode.dispose();
super.dispose();
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
resizeToAvoidBottomPadding:false,//这避免了溢出错误
appBar:appBar(
标题:文本(“文本场动画演示”),
),
body:new InkWell(//用于在用户从文本字段中弹出标签时关闭键盘
splashColor:Colors.transparent,
onTap:(){
FocusScope.of(context.requestFocus(FocusNode());
},
子:容器(
填充:常数边集全部(20.0),
子:列(
儿童:[
SizedBox(高度:_animation.value),
TextFormField(
装饰:输入装饰(
labelText:“我移动!”,
),
focusNode:_focusNode,
)
],
),
),
),
);
}
}
只需将您的身体代码剪切并粘贴到该文件中即可-
SingleChildScrollView(
child: Stack(
children: <Widget>[
// your body code
],
),
),
SingleChildScrollView(
子:堆栈(
儿童:[
//你的身体密码
],
),
),
实现这一点的一个非常简单的方法是使用MediaQuery获取底部视图插入。这将如下所示:
...
return Row(
children: <Widget>[
TextField(
decoration: InputDecoration.collapsed(hintText: "Start typing ..."),
controller: _chatController,
),
SizedBox(
height: MediaQuery.of(Context).viewInsets.bottom,
),
],
);
...
。。。
返回行(
儿童:[
文本字段(
装饰:输入装饰。折叠(hintText:“开始键入…”),
控制器:\ u chatController,
),
大小盒子(
高度:MediaQuery.of(Context).viewInsets.bottom,
),
],
);
...
希望有帮助
<activity
android:name="..ActivityName"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"/>
仅适用于android
如果对活动使用windowSoftInputMode添加configChanges和windowSoftInputMode
另一种方式
将文本字段添加到列表视图
ListView(
children: <Widget>[
TextField(),
TextField(),
]
)
ListView(
儿童:[
TextField(),
TextField(),
]
)
脚手架(
resizeToAvoidBottomInset:true,
正文:SingleChildScrollView(
子:容器(
子:列(
儿童:[
TextFormField(
装饰:输入装饰(
labelText:“输入文本”,
),
),TextFormField(
装饰:输入装饰(
labelText:“输入文本”,
),
),TextFormField(
装饰:输入装饰(
labelText:“输入文本”,
),
),TextFormField(
装饰:输入装饰(
labelText:“输入文本”,
),
),TextFormField(
装饰:输入装饰(
labelText:“输入文本”,
),
),TextFormField(
装饰:输入装饰(
labelText:“输入文本”,
),
),TextFormField(
装饰:输入装饰(
labelText:“输入文本”,
),
),
TextFormField(
装饰:输入装饰(
labelText:“输入文本”,
),
)
],
),
),
)
);
//resizeToAvoidBottomPadding:false已删除
使用resizeToAvoidBottomInset:true
最简单的方法就是用 SingleChildScrollView(…) 当文本字段位于页面底部且键盘出现时,文本字段将自动向上滚动。然后可以在键盘正上方输入文本。我在这里的方式
Scaffold(
resizeToAvoidBottomInset: false,
resizeToAvoidBottomPadding: false,
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/Bg img.png'), fit: BoxFit.fill)),
child: Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: CustomScrollView(
slivers: [
SliverFillRemaining(
hasScrollBody: false,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
.............
此模板有一些优点:
- 当键盘出现时,向上移动内容
- 在滚动视图中使用空格键的列
- 背景是粘贴的手机屏幕,从不更改键盘ups
嵌套滚动视图中有自定义滚动视图
,则上述操作不起作用
首先,需要为TextField指定一个focusNode
TextField(focusNode:_focusNode(),
...);
用于访问嵌套滚动视图的innerScrollController
。您可以查看有关如何获取innerScrollController的示例。声明globalKey并将其分配给NestedScrollView
body: NestedScrollView(
key: globalKey,
...)
设置focusNode
侦听器,以便在文本字段被激活时侦听,并在中设置动画
body: NestedScrollView(
key: globalKey,
...)
void initState() {
super.initState();
_focusNode.addListener(() {
if (_focusNode.hasFocus) {
double innerOffSet = globalKey.currentState.innerController.offset;
if(innerOffSet < 100)
globalKey.currentState.innerController.jumpTo(innerOffSet+100);
}
});
}
var _contentController;
void _settingModalBottomSheet(BuildContext context, String initialText) {
_contentController = new TextEditingController(text: initialText);
showModalBottomSheet(
context: context,
isDismissible: true,
builder: (BuildContext bc) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
height: 40,
margin: EdgeInsets.only(left: 4, right: 4, bottom: 8),
decoration: BoxDecoration(
color: AppColor.bgTextFieldComment,
borderRadius: BorderRadius.circular(16),
),
child: Row(
children: <Widget>[
Expanded(
child: Padding(
padding: EdgeInsets.only(left: 24),
child: TextField(
focusNode: _contentFocusNode,
autofocus: true,
controller: _contentController,
decoration: InputDecoration(
hintText: 'Enter Content',
border: InputBorder.none,
fillColor: AppColor.bgTextFieldComment,
),
keyboardType: TextInputType.multiline,
maxLines: null,
style: TextStyle(
color: Colors.black87,
fontSize: 16,
fontStyle: FontStyle.normal,
),
)),
),
InkWell(
child: Padding(
padding: EdgeInsets.only(left: 4, right: 4),
child: Icon(
Icons.send,
color: Colors.blue,
),
),
onTap: () {
// do ON TAP
},
),
],
),
),
SizedBox(
height: MediaQuery.of(bc).viewInsets.bottom,
),
],
);
},).then((value) {
print('Exit Modal');
});
print('request focus');
_contentFocusNode.requestFocus();
}
double bottomInsets = MediaQuery.of(context).viewInsets.bottom;
return ListView(
children:[
...widgets,
Container(
margin:EdgeInsets.only(
top:1.0,
left:1.0,
right:1.0,
bottom:_focusNode.hasFocus && bottomInsets != 0?
_animation.value : 1.0),
child:TextFormField(
decoration: InputDecoration(
labelText: 'I move!',
),
focusNode: _focusNode,
scrollPadding: EdgeInsets.only(bottom:bottomInsets + 40.0),
),
),
]
);
Form(
child: Column(
children: <Widget> [
TextFormField(),
TextFormField(),
...
TextFormField(),
]
)
)
Column(
children: [
Expanded(
child:// Top View,
),
postSend // edittext. and button
],
)
Flexible(
child: Image(
image :
AssetImage('assets/logo.png'),
),
),