我正在构建Flutter应用程序,主要用于iOS。
我的一个视图有一个文本字段,当您点击它时会出现iOS键盘。问题是-布局无法像在本地iOS应用中一样平滑地更改。取而代之的是,它甚至会在键盘打开动画完成之前立即跳到最终可用的屏幕高度。
我尝试将我的SafeArea元素包装在AnimatedSize
和AnimatedContainer
中-并没有帮助。
我的布局代码:
SafeArea(child:
Column(children:[
TextField(...)
])
)
当键盘出现时,如何使布局平滑调整大小?
答案 0 :(得分:2)
此功能是必需的,但从2020年5月起尚未实现。请随时对其进行投票以使其具有更高的优先级:https://github.com/flutter/flutter/issues/19279
正在实施的同时,您可以使用https://pub.dev/packages/keyboard_attachable
答案 1 :(得分:1)
使用 AnimatedPadding Widget 可以实现所需的输出,虽然这并不完美,但总比没有好:d
Open issue as of 15/03/21, for reference
import 'dart:math';
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
bottom: false,
child: Scaffold(
// !!! Important part > to disable default scaffold insets
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text("Appbar Title"),
),
body: Stack(
children: [
Scrollbar(
child: ListView.builder(
padding: EdgeInsets.all(0.0),
itemCount: 30,
itemBuilder: (context, i) {
return Container(
height: 100,
width: double.infinity,
color: Colors
.primaries[Random().nextInt(Colors.primaries.length)],
);
},
),
),
Align(
alignment: Alignment.bottomLeft,
child: AnimatedPadding(
padding: MediaQuery.of(context).viewInsets,
// You can change the duration and curve as per your requirement:
duration: const Duration(milliseconds: 200),
curve: Curves.decelerate,
child: InputField()),
)
],
)),
);
}
}
class InputField extends StatefulWidget {
InputField({Key key}) : super(key: key);
@override
_InputFieldState createState() => _InputFieldState();
}
class _InputFieldState extends State<InputField> {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey[100],
padding: const EdgeInsets.symmetric(vertical: 6),
child: Row(
children: [
SizedBox(
width: 60,
child: Icon(Icons.add_a_photo),
),
Flexible(
child: TextField(
style: Theme.of(context).textTheme.bodyText1,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Enter text...',
),
),
),
SizedBox(
width: 60,
child: Icon(Icons.send),
),
],
),
);
}
}
答案 2 :(得分:0)
您可以使用此程序包keyboard_visibility并收听keyboard visibility
。然后,您可以给出实现功能的逻辑,就像可以缩短起始container
的高度一样。那不是完美的。但是我认为这是目前的唯一方法。
答案 3 :(得分:0)
我使用类似的东西:
AnimatedPadding(
padding: MediaQuery.of(context).viewInsets,
duration: const Duration(milliseconds: 100),
curve: Curves.decelerate,
child: ....
)
这会根据 viewInsets(软件键盘高度)为 padding 设置动画。
答案 4 :(得分:0)
您需要使用 keyboard_visibility 包并使用它来触发您的 AnimatedContainer 或 AnimatedPadding
bool _isKeyboardActive = false;
@override
void initState() {
super.initState();
//add keyboard visibility Listener
KeyboardVisibility.onChange.listen((event) {
setState(() {
_isKeyboardActive = event;
});
});
}
Widget build(BuildContext context){
return AnimatedContainer(
width: _isKeyboardActive ? 200 : MediaQuery.of(context).size.width,
height: 60,
color: Colors.red,
duration: Duration(milliseconds: 600)
)
}
以此为基础。
答案 5 :(得分:-1)
您应该尝试像这样设置resizeToAvoidBottomPadding: false
:
return Scaffold(
key: _scaffoldKey,
resizeToAvoidBottomPadding: false,