我有一个带有DefaultTabController的页面,该页面是:
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
resizeToAvoidBottomPadding: true,
appBar: AppBar(
bottom: TabBar(
indicatorColor: Colors.red,
indicator: BoxDecoration(
color: buttonColor,
),
tabs: [Tab(text: "Login"), Tab(text: "Register", key: Key("tabRegistro"))],
),
centerTitle: true,
title: Text(appBarTitle)),
body: TabBarView(
children: [
new LoginPage(),
new RegisterPage(),
],
),
),
);
}
例如,LoginPage构建为:
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: true,
key: _scaffoldKey,
body: SingleChildScrollView(
child: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: Center(
child: Container(
color: backgroundColor,
child: Padding(
padding: const EdgeInsets.all(36.0),
child: Form(
key: formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 155.0,
child: Image.asset(
"assets/images/pet.PNG",
fit: BoxFit.contain,
),
),
SizedBox(height: 20.0),
emailField,
SizedBox(height: 10.0),
passwordField,
SizedBox(height: 20.0),
loginButon,
SizedBox(height: 20.0),
GoogleSignInButton(
darkMode: true,
text: "Login with Google",
onPressed: () {
_sigIn();
}),
],
),
)),
),
),
)));
}
但是,当我写作时,键盘覆盖了文本字段,并且它们不可见。
使用SingleChildScrollView
之前可以使用,但是现在不能正常使用了。我尝试放入resizeToAvoidBottomPadding: true
,但不起作用。我该怎么做才能解决此问题?
答案 0 :(得分:0)
代码正常,问题出在Android.manifest.xml。我使用的是Android Simulator,并且为了隐藏状态栏,我将这些行放在了这行:
<script type = "text/javascript" src = "path_to test.js"></script>
如果我把原始行放了,那就行了。原始行是:
android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen"
答案 1 :(得分:0)
将每个TextFormField
用以下小部件包装
首先创建一个单独的文件,我们将其称为ensure_visible.dart
,其中包含:
import 'dart:async';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:meta/meta.dart';
class EnsureVisibleWhenFocused extends StatefulWidget {
const EnsureVisibleWhenFocused({
Key key,
@required this.child,
@required this.focusNode,
this.curve: Curves.ease,
this.duration: const Duration(milliseconds: 100),
}) : super(key: key);
/// The node we will monitor to determine if the child is focused
final FocusNode focusNode;
/// The child widget that we are wrapping
final Widget child;
/// The curve we will use to scroll ourselves into view.
///
/// Defaults to Curves.ease.
final Curve curve;
/// The duration we will use to scroll ourselves into view
///
/// Defaults to 100 milliseconds.
final Duration duration;
EnsureVisibleWhenFocusedState createState() => new EnsureVisibleWhenFocusedState();
}
class EnsureVisibleWhenFocusedState extends State<EnsureVisibleWhenFocused> {
@override
void initState() {
super.initState();
widget.focusNode.addListener(_ensureVisible);
}
@override
void dispose() {
super.dispose();
widget.focusNode.removeListener(_ensureVisible);
}
Future<Null> _ensureVisible() async {
// Wait for the keyboard to come into view
// TODO: position doesn't seem to notify listeners when metrics change,
// perhaps a NotificationListener around the scrollable could avoid
// the need insert a delay here.
await Future.delayed(const Duration(milliseconds: 300));
if (!widget.focusNode.hasFocus)
return;
final RenderObject object = context.findRenderObject();
final RenderAbstractViewport viewport = RenderAbstractViewport.of(object);
assert(viewport != null);
ScrollableState scrollableState = Scrollable.of(context);
assert(scrollableState != null);
ScrollPosition position = scrollableState.position;
double alignment;
if (position.pixels > viewport.getOffsetToReveal(object, 0.0).offset) {
// Move down to the top of the viewport
alignment = 0.0;
} else if (position.pixels < viewport.getOffsetToReveal(object, 1.0).offset) {
// Move up to the bottom of the viewport
alignment = 1.0;
} else {
// No scrolling is necessary to reveal the child
return;
}
position.ensureVisible(
object,
alignment: alignment,
duration: widget.duration,
curve: widget.curve,
);
}
Widget build(BuildContext context) => widget.child;
}
在您的身份验证页面中,只需导入ensure_visible
,然后执行以下操作
TextFormField
,您必须像创建FocusNode
final _usernameFocusNode = FocusNode();
final _emailFocusNode = FocusNode();
让我们以这种构建方法为例:
Widget _buildUserNameTextField() {
return EnsureVisibleWhenFocused(
focusNode: _usernameFocusNode,
child: TextFormField(
focusNode: _usernameFocusNode,
),
);
}
注意:对于FocusNode
和EnsureVisibleWhenFocused
,您都必须传递相同的TextFormField