问题
In flutter app, when an input field is wrapped inside Scrollable, Opacity, Stack, when keyboard appear, the scrollable view is not correctly placed.
How to make the scrollable view correctly when keyboard appear?
If input field is not wrapped inside Scrollable, the keyboard is not appear at all. It can be test by changing ListView
with Column in the following code.
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:
The problem is that you're nesting a Scaffold
inside a Scaffold
and each scaffold is trying to add padding for the keyboard. You should only ever use one Scaffold
at a time. Instead of having an inner Scaffold
, consider using Column
to position your AppBar
at the top of the screen.
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'),
),
],
),
);
}
}
来源:https://stackoverflow.com/questions/46500186/flutter-keyboard-issue-when-wrap-under-stack-opacity-scrollable