簡體   English   中英

路由后,TextField 單擊重建/重新加載小部件

[英]TextField click rebuilds/reloads widget after routed

我遇到了一個問題,即在使用文本字段時重新加載整個屏幕小部件。 當應用程序將此屏幕作為登錄頁面加載時,不會發生這種情況。

但是當從另一個頁面路由到這個頁面並且單擊文本字段時,就會發生重建。

我什至嘗試了一個簡單的應用程序,並且正在重現。 嘗試了很多方法,但無法找到解決方案。

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';


class Screen1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Screen 1"), // screen title
      ),
      body: new Center(
        child: new Column(
          children: <Widget>[
            new RaisedButton(
              onPressed: () {
                button1(context);
              },
              child: new Text("Go to Screen 2"),
            )
          ],
        ),
      ),
    );
  }
}

class Screen2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("Widget rebuilds");
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Screen 2"),
      ),
      body: new Center(
        child: new Column(
          children: <Widget>[
            new Container(
                height: 350.0,
                child: TextFormField(
                  keyboardType: TextInputType.text,
                  style: TextStyle(fontSize: 16.0, color: Colors.black),
                )),

          ],
        ),
      ),
    );
  }
}

void main() {
  runApp(new MaterialApp(
    home: new Screen1(),
    routes: <String, WidgetBuilder>{
      '/screen2': (BuildContext context) => new Screen2()
    },
  ));
}

void button1(BuildContext context) {
  print("Button 1");
  Navigator.of(context).pushNamed('/screen2');
}

這里應用程序加載了屏幕 1,單擊按鈕轉到屏幕 2 將加載帶有文本字段的屏幕 2。 單擊此字段將顯示鍵盤,單擊鍵盤上的完成並再次關注文本字段將重建屏幕。 當鍵盤出現和消失時,這種情況會不斷發生。

但是如果 Screen2 被設置為登陸頁面,那么點擊文本字段並執行上述相同的過程將不會重新加載小部件。 小部件構建僅發生一次。 似乎問題出在從屏幕 1 導航屏幕 2 時

 runApp(new MaterialApp(
    home: new Screen2(),
    routes: <String, WidgetBuilder>{
      '/screen2': (BuildContext context) => new Screen2()
    },
  ));

這是正常行為,沒有問題。 它實際上在build方法的規范內:它可以被調用任意次數,你應該期望它是這樣。

如果這樣做會導致問題,則很可能您的build函數不是 pure 這意味着它包含副作用,例如 http 調用或類似的。

這些不應該在build方法中完成。 更多細節在這里: 如何處理不需要的小部件構建?


關於“What triggers the build”,常見的有幾種情況:

  • 路由彈出/推送,用於輸入/輸出動畫
  • 屏幕調整大小,通常是由於鍵盤外觀或方向改變
  • 父小部件重新創建了它的子部件
  • 小部件依賴的 InheritedWidget ( Class.of(context)模式) 更改

如果您使用的是 MediaQuery,鍵盤的彈出窗口會觸發 MediaQuery。 所有依賴於 MediaQuery 的小部件都將被重建。 有些包可以替換 MediaQuery 並處理維度,而不會導致不必要的重建,例如 sizer 包。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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