当我选择文本字段时,将显示键盘,但键盘会隐藏我选择的TextField。有人有解决方案吗?
谢谢。
答案 0 :(得分:5)
撰写动画并在TextField获得焦点时向上移动TextField容器。
有关撰写动画的知识,请参阅: Composing Animations and Chaining Animations in Dart's Flutter Framework
使用Flutter的FocusNode检测TextField上的焦点
修改强>
在这里,我写了一个完全符合你想要的例子:
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,
)
],
),
),
),
);
}
}
答案 1 :(得分:3)
Scaffold(
resizeToAvoidBottomInset: true,
body: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
),TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
),TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
),TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
),TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
),TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
),TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
),
TextFormField(
decoration: InputDecoration(
labelText: 'Enter Text',
),
)
],
),
),
)
);
// resizeToAvoidBottomPadding:不推荐使用is
使用resizeToAvoidBottomInset:正确。
答案 2 :(得分:3)
最简单的方法是将其包裹起来
SingleChildScrollView(...)
当文本字段位于页面底部并且出现键盘时,该文本字段会自动向上滚动。然后可以在键盘正上方输入文本。
答案 3 :(得分:1)
只需在此剪切并粘贴您的身体代码-
SingleChildScrollView(
child: Stack(
children: <Widget>[
// your body code
],
),
),
答案 4 :(得分:1)
<activity
android:name="..ActivityName"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"/>
仅适用于android 如果您使用 FlutterFragment ,请为“活动”添加 configChanges 和 windowSoftInputMode 。
另一种方式 将您的TextField添加到ListView
ListView(
children: <Widget>[
TextField(),
TextField(),
]
)
答案 5 :(得分:1)
我在这里的方式
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: [
.............
此模板具有一些优点:
答案 6 :(得分:0)
不需要手动处理动画。只需用SingleChildScrollView
包裹文本字段即可:
SingleChildScrollView(
child: Column(
children: <Widget>[
TextField(),
TextField(),
TextField(),
TextField(),
TextField()
]
)
Flutter中的 SingleChildScrollView
与iOS中的TPKeyboardAvoiding
一样
答案 7 :(得分:0)
一个很短的实现方法是通过使用MediaQuery获取底视图插图。如下所示:
...
return Row(
children: <Widget>[
TextField(
decoration: InputDecoration.collapsed(hintText: "Start typing ..."),
controller: _chatController,
),
SizedBox(
height: MediaQuery.of(Context).viewInsets.bottom,
),
],
);
...
希望有帮助!
答案 8 :(得分:0)
如果您在CustomScrollview
中有NestedScrollView
,以上操作将无效。
首先,您需要为TextField提供一个focusNode。
TextField(focusNode:_focusNode(),
...);
使用NestedScrollViewState来访问innerScrollController
中的NestedScrollView
。您可以查看有关如何获取innerScrollController的示例here。声明一个globalKey并将其分配给NestedScrollView。
body: NestedScrollView(
key: globalKey,
...)
设置focusNode
侦听器以侦听何时激活了文本字段,并相应地为innerScrollController设置动画。
void initState() {
super.initState();
_focusNode.addListener(() {
if (_focusNode.hasFocus) {
double innerOffSet = globalKey.currentState.innerController.offset;
if(innerOffSet < 100)
globalKey.currentState.innerController.jumpTo(innerOffSet+100);
}
});
}
答案 9 :(得分:0)
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();
}
答案 10 :(得分:0)
在我的情况下,我必须结合使用@Javid Noutash
的{{1}}和AnimationController
的{{1}}属性给出的答案。
代码:
在构建方法中添加此行
scrollPadding
添加TextFormField
属性
double bottomInsets = MediaQuery.of(context).viewInsets.bottom;
注意:将此代码与scrollPadding
的代码合并
答案 11 :(得分:0)
使用 TextField
代替 TextFormField
,并使用 TextFormField
到 Form
的列表包装小部件:
Form(
child: Column(
children: <Widget> [
TextFormField(),
TextFormField(),
...
TextFormField(),
]
)
)
答案 12 :(得分:0)
我遇到了同样的问题,其中父小部件是 Material,其他小部件在 ListView 内。当我在没有任何额外代码的情况下将父小部件更改为 Scaffold 并且 TextField(在我的情况下为 TextFormField)自动显示在键盘上方时,问题得到了解决。因此,如果您遇到此问题,只需确保将 Scaffold 作为主要小部件。
答案 13 :(得分:0)
你可以很容易地尝试使用灵活的小部件,只需用它包裹你的小部件
Flexible(
child: Image(
image :
AssetImage('assets/logo.png'),
),
),
答案 14 :(得分:-3)
就我而言,检查代码很容易
Column(
children: [
Expanded(
child:// Top View,
),
postSend // edittext. and button
],
)