Флаттер сохраняет фокусировку текстового поля на изменениях макета - PullRequest
0 голосов
/ 13 марта 2020

У меня есть трепетная страница с текстовым полем, которая имеет совершенно разную разметку в зависимости от того, нахожусь ли я в альбомной или книжной ориентации.

Вот урезанная версия моего кода:

  // These are actually created in initState and destroyed in dispose
  TextEditingController passwordController = TextEditingController();
  FocusNode _focusNode = FocusNode();

  Widget build(BuildContext context) {
    // Build for small screens, like landscape
    if ((MediaQuery.of(context).size.height) < 600) {
      return Material(
          child: Align(
            alignment: Alignment.topCenter,
              child: Container(
                height: MediaQuery.of(context).size.height - MediaQuery.of(context).viewInsets.bottom,
                  padding: EdgeInsets.all(24),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Text("Title),
                      TextFormField(
                        focusNode: _focusNode,
                        controller: passwordController,
                        key: ValueKey("password_dialog"),
                      )
                    ],
                  )
              )
          )
      );
    }
    return AlertDialog(
      title: "Title",
      content: SingleChildScrollView(
          child: ListBody(
            children: <Widget>[
              Container(
                  child: Padding(
                      padding: EdgeInsets.only(),
                      child: TextFormField(
                        focusNode: _focusNode,
                        controller: passwordController,
                        key: ValueKey("password_dialog"),
                     )
                  )
              ),
            ],
          )
      ),
      actions: ...
    );
  }

Это означает, что при повороте экрана дерево виджетов полностью изменяется.

К сожалению, когда это происходит, мое текстовое поле также теряет фокус.

Как я могу предотвратить это? У меня уже есть ключ и узел фокуса в текстовом поле, но это не помогает.

1 Ответ

1 голос
/ 21 марта 2020

Предполагая, что вы используете два совершенно разных дерева для размещения своего текстового поля, а алгоритм сопоставления виджетов с элементами во Flutter переходит на один уровень за раз (поэтому он будет sh выходить из предыдущего состояния, прежде чем он будет выясните, что некоторый виджет все еще нуждается в нем), вы можете использовать GlobalKey для сохранения состояния между сборками.

Ниже приведен пример, который просто должен работать в вашем случае (на основе вашего кода):

class Test extends StatefulWidget {
  Test({Key key}) : super(key: key);

  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
  GlobalKey _textFieldKey;
  FocusNode _focusNode;

  @override
  initState() {
    _textFieldKey = GlobalKey();
    _focusNode = FocusNode();
    super.initState();
  }

  Widget build(BuildContext context) {
    if ((MediaQuery.of(context).size.height) < 600) {
      return Material(
          child: Align(
              alignment: Alignment.topCenter,
              child: Container(
                  height: MediaQuery.of(context).size.height -
                      MediaQuery.of(context).viewInsets.bottom,
                  padding: EdgeInsets.all(24),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Text("Title"),
                      TextFormField(
                        focusNode: _focusNode,
                        key: _textFieldKey,
                      )
                    ],
                  ))));
    }

    return AlertDialog(
        title: Text("Title"),
        content: SingleChildScrollView(
            child: ListBody(
          children: <Widget>[
            Container(
                child: Padding(
                    padding: EdgeInsets.only(),
                    child: TextFormField(
                      focusNode: _focusNode,
                      key: _textFieldKey,
                    ))),
          ],
        )),
        actions: []);
  }
}

Эта топика c подробно объясняется здесь https://www.youtube.com/watch?v=kn0EOS-ZiIc

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...