簡體   English   中英

如何在 flutter 中的兩個屏幕之間導航並顯示鍵盤?

[英]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沒有聚焦並且鍵盤下降。

需要什么:我需要以某種方式使用Navigatorpage 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM