在 Stack > Opacity > Scrollable 下包装时出现颤振键盘问题
Posted
技术标签:
【中文标题】在 Stack > Opacity > Scrollable 下包装时出现颤振键盘问题【英文标题】:Flutter keyboard issue when wrap under Stack > Opacity > Scrollable 【发布时间】:2018-03-12 00:42:36 【问题描述】:在flutter应用中,当输入字段被包裹在Scrollable、Opacity、Stack中时,当键盘出现时,可滚动视图没有正确放置。
当键盘出现时如何正确显示可滚动视图?
如果输入字段没有包裹在 Scrollable 中,则键盘根本不会出现。可以通过在下面的代码中将ListView
更改为Column来测试。
import 'package:flutter/material.dart';
void main()
runApp(new MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return new MaterialApp(
home: new MyHomePage(),
);
class SecurePage extends StatelessWidget
final int index;
SecurePage(this.index);
Widget build(BuildContext context)
return new Scaffold(
appBar: new AppBar(
title: new Text('Secure'),
),
body: new Column(
children: <Widget>[
new Text('No $index'),
new IconButton(
icon: new Icon(Icons.verified_user),
onPressed: ()
Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context)
return new VerifiedPage(index + 1);
,
),
);
,
),
],
),
);
class VerifiedPage extends StatelessWidget
final int index;
VerifiedPage(this.index);
Widget build(BuildContext context)
return new Scaffold(
appBar: new AppBar(
title: new Text('Verity'),
),
body: new ListView(
children: <Widget>[
new Text('No $index'),
new Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: new TextField(
autofocus: index % 2 == 1,
decoration: const InputDecoration(
hintText: 'Search',
),
),
),
new IconButton(
icon: new Icon(Icons.security),
onPressed: ()
Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context)
return new SecurePage(index + 1);
,
),
);
,
),
],
),
);
class MyHomePage extends StatefulWidget
@override
State createState() => new MyHomePageState();
class MyHomePageState extends State<MyHomePage>
int _page = 0;
List<Widget> initialWidgets = <Widget>[
new SecurePage(0),
new VerifiedPage(0),
];
Widget build(BuildContext context)
return new Scaffold(
body: new Stack(
children: new List<Widget>.generate(initialWidgets.length, (int index)
return new IgnorePointer(
ignoring: index != _page,
child: new Opacity(
opacity: _page == index ? 1.0 : 0.0,
child: new Navigator(
onGenerateRoute: (RouteSettings settings)
return new MaterialPageRoute(
builder: (_) => initialWidgets[index],
);
,
),
),
);
),
),
bottomNavigationBar: new BottomNavigationBar(
currentIndex: _page,
onTap: (int index)
setState(()
_page = index;
);
,
items: <BottomNavigationBarItem>[
new BottomNavigationBarItem(
icon: new Icon(Icons.security),
title: new Text('Secure'),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.verified_user),
title: new Text('Verified'),
),
],
),
);
【问题讨论】:
【参考方案1】:问题是您将Scaffold
嵌套在Scaffold
中,并且每个脚手架都在尝试为键盘添加填充。您一次只能使用一个Scaffold
。考虑使用Column
将AppBar
定位在屏幕顶部,而不是使用内部Scaffold
。
import 'package:flutter/material.dart';
void main()
runApp(new MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return new MaterialApp(
home: new MyHomePage(),
);
class SecurePage extends StatelessWidget
final int index;
SecurePage(this.index);
Widget build(BuildContext context)
return new Column(
children: <Widget>[
new AppBar(
title: new Text('Secure'),
),
new Text('No $index'),
new IconButton(
icon: new Icon(Icons.verified_user),
onPressed: ()
Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context)
return new VerifiedPage(index + 1);
,
),
);
,
),
],
);
class VerifiedPage extends StatelessWidget
final int index;
VerifiedPage(this.index);
Widget build(BuildContext context)
return new Column(
children: <Widget>[
new AppBar(
title: new Text('Verity'),
),
new Text('No $index'),
new Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: new TextField(
autofocus: index % 2 == 1,
decoration: const InputDecoration(
hintText: 'Search',
),
),
),
new IconButton(
icon: new Icon(Icons.security),
onPressed: ()
Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context)
return new SecurePage(index + 1);
,
),
);
,
),
],
);
class MyHomePage extends StatefulWidget
@override
State createState() => new MyHomePageState();
class MyHomePageState extends State<MyHomePage>
int _page = 0;
List<Widget> initialWidgets = <Widget>[
new SecurePage(0),
new VerifiedPage(0),
];
Widget build(BuildContext context)
return new Scaffold(
body: new Stack(
children: new List<Widget>.generate(initialWidgets.length, (int index)
return new IgnorePointer(
ignoring: index != _page,
child: new Opacity(
opacity: _page == index ? 1.0 : 0.0,
child: new Navigator(
onGenerateRoute: (RouteSettings settings)
return new MaterialPageRoute(
builder: (_) => initialWidgets[index],
);
,
),
),
);
),
),
bottomNavigationBar: new BottomNavigationBar(
currentIndex: _page,
onTap: (int index)
setState(()
_page = index;
);
,
items: <BottomNavigationBarItem>[
new BottomNavigationBarItem(
icon: new Icon(Icons.security),
title: new Text('Secure'),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.verified_user),
title: new Text('Verified'),
),
],
),
);
【讨论】:
哦,Flutter 在布局上总是给我惊喜。我虽然 AppBar 总是需要在 Scaldfold 里面。我认为它还有其他问题和文件a bug report。 @KyawTun 我不认为这是一个错误,我不确定您为什么要使用这种复杂的布局,但是验证出现在安全之上并且对于触摸事件是不可见的,看看我意思是尝试设置ignoring: false
并在Verify页面添加TextEditingController
到你的TextField
,并设置onChanged
属性打印控制器的内容,你会发现你正在输入Verify的TextField
当您在安全页面上时,因为它位于其顶部。以上是关于在 Stack > Opacity > Scrollable 下包装时出现颤振键盘问题的主要内容,如果未能解决你的问题,请参考以下文章