如何等到键盘在颤动中打开?
How to wait until keyboard is opened in flutter?
我需要在文本字段获得焦点时滚动页面。
所以我使用了 scroll_to_index 插件(https://pub.dev/packages/scroll_to_index).
但它只有在键盘已经打开的情况下才能正常运行。
如果我在键盘未打开时点击文本字段,它不会滚动页面。
我认为这是因为在打开键盘之前滚动了页面。
在我看来,问题的出现似乎是因为代码是这样工作的。
1.tap 一个文本字段(链接的焦点节点有焦点)
2. 它尝试将页面滚动到目标。但是因为现在键盘还没有打开,目标已经在视图中了。所以看起来什么都没发生。
3.键盘打开,隐藏内容
auto_scroll.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
class MyCustomScrollView extends StatefulWidget {
@override
_MyCustomScrollViewState createState() => _MyCustomScrollViewState();
}
class _MyCustomScrollViewState extends State<MyCustomScrollView> {
AutoScrollController _autoScrollController = new AutoScrollController();
List<FocusNode> nodes = List<FocusNode>.generate(3, (index) => FocusNode());
Future _scrollToIndex(int index) async {
await _autoScrollController.scrollToIndex(index,
preferPosition: AutoScrollPosition.end);
}
@override
void initState() {
super.initState();
for(var i =0;i<3;i++) {
nodes[i].addListener(() {
if(nodes[i].hasFocus) _scrollToIndex(i);
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
body: CustomScrollView(
controller: _autoScrollController,
slivers: [
SliverToBoxAdapter(
child: Container(
child: Column(
children: [
SizedBox(height: 100),
CupertinoTextField(
focusNode: nodes[0],
onEditingComplete: (){
FocusScope.of(context).requestFocus(nodes[1]);
},
),
AutoScrollTag(
key: ValueKey(0),
controller: _autoScrollController,
index: 0,
child: Container(height: 300, color : Colors.green)
),
CupertinoTextField(
focusNode: nodes[1],
onEditingComplete: (){
FocusScope.of(context).requestFocus(nodes[2]);
},
),
AutoScrollTag(
key: ValueKey(1),
controller: _autoScrollController,
index: 1,
child: Container(
height: 300,
color : Colors.green,
child: Center(
child: Text("Here should be visible!!!!"),
),
)
),
CupertinoTextField(
focusNode: nodes[2],
),
AutoScrollTag(
key: ValueKey(2),
controller: _autoScrollController,
index: 2,
child: Container(height: 300, color : Colors.green)
),
],
),
)
)
],
),
);
}
}
这是代码。当我点击第二个文本字段时,它应该滚动以显示第二个文本字段下方的所有红色容器,但事实并非如此。
但是当键盘打开时,单击第二个文本字段可以正常工作。
我点击第二个文本字段时的预期结果
实际发生了什么
我知道只需将焦点放在文本字段上就足以滚动到文本字段。但是在我的应用程序中,我在键盘上方有一个 Positioned 栏,所以我遇到了 Positioned 栏覆盖文本字段的情况。这就是我使用 scroll_to_index.
的原因
所以我要做的是等待键盘出现,然后当键盘出现时,运行 _scrollToIndex 函数。我怎样才能等到键盘打开?或者这个问题有什么好的解决方案吗?感谢您的阅读。
您可以使用 flutter_keyboard_visibility. There are 2 ways of implementation: with provider and with listener.
我需要在文本字段获得焦点时滚动页面。
所以我使用了 scroll_to_index 插件(https://pub.dev/packages/scroll_to_index).
但它只有在键盘已经打开的情况下才能正常运行。
如果我在键盘未打开时点击文本字段,它不会滚动页面。
我认为这是因为在打开键盘之前滚动了页面。
在我看来,问题的出现似乎是因为代码是这样工作的。
1.tap 一个文本字段(链接的焦点节点有焦点)
2. 它尝试将页面滚动到目标。但是因为现在键盘还没有打开,目标已经在视图中了。所以看起来什么都没发生。
3.键盘打开,隐藏内容
auto_scroll.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
class MyCustomScrollView extends StatefulWidget {
@override
_MyCustomScrollViewState createState() => _MyCustomScrollViewState();
}
class _MyCustomScrollViewState extends State<MyCustomScrollView> {
AutoScrollController _autoScrollController = new AutoScrollController();
List<FocusNode> nodes = List<FocusNode>.generate(3, (index) => FocusNode());
Future _scrollToIndex(int index) async {
await _autoScrollController.scrollToIndex(index,
preferPosition: AutoScrollPosition.end);
}
@override
void initState() {
super.initState();
for(var i =0;i<3;i++) {
nodes[i].addListener(() {
if(nodes[i].hasFocus) _scrollToIndex(i);
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
body: CustomScrollView(
controller: _autoScrollController,
slivers: [
SliverToBoxAdapter(
child: Container(
child: Column(
children: [
SizedBox(height: 100),
CupertinoTextField(
focusNode: nodes[0],
onEditingComplete: (){
FocusScope.of(context).requestFocus(nodes[1]);
},
),
AutoScrollTag(
key: ValueKey(0),
controller: _autoScrollController,
index: 0,
child: Container(height: 300, color : Colors.green)
),
CupertinoTextField(
focusNode: nodes[1],
onEditingComplete: (){
FocusScope.of(context).requestFocus(nodes[2]);
},
),
AutoScrollTag(
key: ValueKey(1),
controller: _autoScrollController,
index: 1,
child: Container(
height: 300,
color : Colors.green,
child: Center(
child: Text("Here should be visible!!!!"),
),
)
),
CupertinoTextField(
focusNode: nodes[2],
),
AutoScrollTag(
key: ValueKey(2),
controller: _autoScrollController,
index: 2,
child: Container(height: 300, color : Colors.green)
),
],
),
)
)
],
),
);
}
}
这是代码。当我点击第二个文本字段时,它应该滚动以显示第二个文本字段下方的所有红色容器,但事实并非如此。 但是当键盘打开时,单击第二个文本字段可以正常工作。
我点击第二个文本字段时的预期结果
实际发生了什么
我知道只需将焦点放在文本字段上就足以滚动到文本字段。但是在我的应用程序中,我在键盘上方有一个 Positioned 栏,所以我遇到了 Positioned 栏覆盖文本字段的情况。这就是我使用 scroll_to_index.
的原因所以我要做的是等待键盘出现,然后当键盘出现时,运行 _scrollToIndex 函数。我怎样才能等到键盘打开?或者这个问题有什么好的解决方案吗?感谢您的阅读。
您可以使用 flutter_keyboard_visibility. There are 2 ways of implementation: with provider and with listener.