[英]How to navigate between two screens in flutter and show keyboard?
我有一些下一個(簡化的)小部件樹結構:
- home (stack of widgets)
- page container
- editText field
如您所見,編輯文本將始終位於頁面頂部,我將與Navigator.of(context)
事務交換。
問題:當我關注editText
時,鍵盤出現。 當用戶開始打字時,有時我需要在page container
內推送另一個屏幕。 當我使用Navigator.of()
時 - editText
沒有聚焦並且鍵盤下降。
需要什么:我需要以某種方式使用Navigator
在page container
中進行轉換(推送/彈出/替換)並保持鍵盤仍然向上(保持 editText 為焦點)。
你知道怎么做嗎?
您的用例看起來很奇怪,但我想您有充分的理由遵循此設置。
無論如何,問題是在調用Navigator.push
時, TextField
沒有聚焦。 這不是一個錯誤,而是一個預期的功能(我認為)是為了防止鍵盤跟隨您進入下一個沒有TextField
的屏幕。 但是我知道這對您的用例來說是個問題。
我的解決方案(不是我承認的最漂亮的,但我唯一可以工作的)是手動強制將焦點返回到TextField
。 你需要兩個組件:
TextField
相關聯的FocusNode
以偵聽以檢查您的TextField
是否從聚焦變為未聚焦。 如果設置了focusOnNextUnfocus
,它應該在 unfocus 之后重新請求焦點focusOnNextUnfocus
一個布爾值,在推送之前設置為true
,一旦再次請求焦點,它將設置為 false。這是您提供的代碼的改編:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
/// Handles the focus state of our text field
final focusNode = FocusNode();
/// A bool to keep track on whether we should refocus after
/// unfocus. This will be set to `true` before pushing
var focusOnNextUnfocus = false;
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
void initState() {
focusNode.addListener(() {
// If we no longer have the focus and should refocus, we refocus
if (!focusNode.hasFocus && focusOnNextUnfocus) {
focusNode.requestFocus();
focusOnNextUnfocus = false; // Reset to false once it has been processed
}
});
super.initState();
}
@override
void dispose() {
focusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
late BuildContext anotherContext;
final edit = TextField(
focusNode: focusNode,
onChanged: (String value) async {
if (value.length > 4) {
// Pop does not unfocus so no worries here
Navigator.pop(anotherContext);
} else if (value.length > 3) {
// Push DOES unfocus, so we need to set focusOnNextUnfocus to true
focusOnNextUnfocus = true;
Navigator.of(anotherContext).push(
MaterialPageRoute(builder: (_) {
return Builder(builder: (context) {
return Another();
});
}),
);
}
},
);
final scaffold = MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Builder(
builder: (context) {
anotherContext = context;
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
),
);
return Scaffold(
body: Stack(
children: [
Positioned(child: scaffold),
Align(
alignment: Alignment.center,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16),
child: edit,
),
),
],
),
);
}
}
class Another extends StatelessWidget {
const Another({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.