今年は、Flutterを使用し、いくつかのアプリをリリースすることができました。
その中で、会員登録などの入力ページでチームのスタンダードになってきているなぁという部分がありましたので紹介したいと思います。
入力ページのイメージ
会員登録ページを例にあげると、現在担当しているアプリは下記のような、一度に情報を登録せず、ページ遷移させる事が多いです。
body: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('XXXXXを入力してください。'),
Text('XXXXXはあとからマイページにて変更することも可能です。'),
],
),
),
TextField(),
Expanded(child: Container()),
Padding(
padding: EdgeInsets.only(bottom: 50),
child: RaisedButton(child: Text('次へ進む')),
),
])
縦に長い場合エラー
しかし文言が増えたときなど、縦幅が長くなった場合、bottom overflowedエラーが出てしまいます。
対策として、画面をタップするとキーボードが閉じる処理を入れます。
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Column(children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('XXXXXを入力してください。'),
Container(
height: 500,
color: Colors.green,
),
],
),
),
TextField(),
Expanded(child: Container()),
Padding(
padding: EdgeInsets.only(bottom: 50),
child: RaisedButton(child: Text('次へ進む')),
)
])),
resizeToAvoidBottomInset: false, //追加部分
全体を GestureDetector
で囲み、 onTap
でフォーカスを外す処理を入れ、キーボードを隠すようにします。
また、 resizeToAvoidBottomInset
でキーホードの表示/非表示でボタンの位置が変わらないようにします。
もっと長い場合は
ページが長い場合はスクロール処理を入れますが、スクロールを行なった際にもキーボードを閉じる処理を入れたいです。
body: NotificationListener(
child: SingleChildScrollView(
dragStartBehavior: DragStartBehavior.down,
child: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Column(children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('XXXXXを入力してください。'),
Text('XXXXXはあとからマイページにて変更することも可能です。'),
Container(
height: 500,
color: Colors.green,
),
],
),
),
TextField(),
Padding(
padding: EdgeInsets.only(top: 50, bottom: 50),
child: RaisedButton(child: Text('次へ進む')),
)
]))),
onNotification: (ScrollNotification scrollInfo) {
FocusScope.of(context).unfocus();
}),
resizeToAvoidBottomInset: false,
SingleChildScrollView
で全体を囲み、 さらに NotificationListener
で囲みます。
Expanded
はスクロールの中に入れられないので外します。
onNotification
でスクロールが発生した際にフォーカスを外す処理を入れて出来上がりです。