我已經嘗試學習這個概念一個多月了,但我似乎無法以更簡單的方式弄清楚 GlobalKeys 和各種型別的鍵到底是什么,它是僅用于表單驗證器還是用于更多目的,沒有在 youtube 上也沒有明確的基本示例,或者也許某處有一本書?
在基本的顫振應用程式中
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter ;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
這里有像
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
\\\\
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
Key /super 關鍵字與它有什么關系或我們如何使用它?
uj5u.com熱心網友回復:
我發現這非常有幫助:https : //medium.com/flutter/keys-what-are-they-good-for-13cb51742e7d
我發現 GlobalKeys 有兩種用途(我確定還有更多用途):
第一個:這就是上面文章討論的內容:如何將狀態物件鏈接到小部件。我將在這里過分簡化一些事情。
通常,flutter 不會使用全域鍵。當您創建一個有狀態小部件時,會創建兩個物件:一個小部件和它的狀態。這個想法是小部件本身將在構建結束時(或在它被繪制到螢屏上之后)被銷毀。一旦您再次啟動構建(例如通過 setState()) - 將重新創建一個小部件。
當然 - 您希望狀態物件在更改之間保持不變 - 畢竟這是您存盤資料的地方。并且您希望 Flutter 將您的狀態物件鏈接回新創建的 Widget 物件實體。
大多數情況下,這對 Flutter 來說是一件容易的事情——它只會在相同的位置找到相同的小部件,將其鏈接到它的狀態物件,然后就完成了。
如果您的小部件在下一個構建中移動 - 這將不起作用,并且將創建新的狀態物件并且您將失去您的狀態。
看看這個經過修改的 Flutter Counter 應用程式 - 我將計數器移動到一個單獨的小部件中,但也將它鏈接回原始的 _MyHomePageState。每次我們重建主小部件時,我們都會翻轉列中按鈕和文本框的順序 - 您會看到計數永遠不會改變:它始終顯示為零。
由于小部件改變了位置,它的狀態被洗掉并創建了新的狀態。
您可以在 dartpad 中快速運行它:
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({
Key? key,
required this.title,
}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var _key=GlobalKey();
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter ;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (_counter.isOdd) Counter(onPressed: _incrementCounter),
const Text(
'You have pushed the button this many times:',
),
if (_counter.isEven) Counter(onPressed: _incrementCounter),
],
),
),
);
}
}
class Counter extends StatefulWidget {
final VoidCallback onPressed;
const Counter({Key? key, required this.onPressed}) : super(key: key);
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter ;
});
widget.onPressed();
}
@override
Widget build(BuildContext context) {
return Column(children: [
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
ElevatedButton(
style:
ElevatedButton.styleFrom(textStyle: const TextStyle(fontSize: 20)),
onPressed: _incrementCounter,
child: const Text('Increment'),
)
]);
}
}
現在只需將 GlobalKey 添加到 Counter 小部件(在兩個呼叫中),我們就可以幫助 flutter 鏈接狀態物件。請注意,我們在狀態物件中創建了一次 _key 值 - 因為我們希望每次都傳遞相同的鍵(否則有什么意義......)
Counter(onPressed: _incrementCounter, key: _key),
在此更改之后,即使 Widget 更改了螢屏上的位置和順序 - 您的狀態也會保持不變。
現在你會問:為什么 Flutter 不會默認為所有 Widget 執行此操作?事實證明 - GlobalKeys 的維護成本非常高,如果你想每秒渲染 60 幀(每幀 16 毫秒) - 你想要優化每一步。通過“默認沒有鍵”的方法,一切都得到了優化,并且在大多數情況下都可以作業——但在少數情況下,當你需要全域鍵時——你需要了解一點,而且使用起來非常簡單。
我為它找到的第二個用途:您需要全域鍵才能在呈現后在螢屏上找到確切的 Widget 位置。Widget 本身不會知道它會在哪里結束,您只有在渲染完成后才知道這一點。如果你想做自定義影片或類似的東西,你需要這個。
這是一個簡單的函式,它會告訴您小部件的位置:
Rect getRectFromKey(GlobalKey key) {
RenderBox renderBox = (key.currentContext!.findRenderObject())! as RenderBox;
var targetPosition = renderBox.localToGlobal(Offset.zero);
var targetSize = renderBox.size;
// A Rect can be created with one its constructors or from an Offset and a Size using the & operator:
Rect rect = targetPosition & targetSize;
return rect;
}
uj5u.com熱心網友回復:
全域鍵用于表單驗證。Flutter 中除了全域鍵之外還有值、物件和唯一鍵。通過以下鏈接,您可以清楚地了解所有這些。
Flutter 中的鍵
uj5u.com熱心網友回復:
- 考慮到這些小部件保持某種狀態,除非它們具有唯一鍵,否則小部件樹中相同型別和相同級別的多個小部件可能不會按預期更新。
- 顯式設定小部件的鍵有助于 Flutter 了解在狀態更改時需要更新哪個小部件。
- 鍵還存盤和恢復小部件串列中的當前滾動位置。
考慮狀態不變,全域鍵通常用于從應用程式的任何部分更改父小部件。全域鍵比簡而言之鍵更廣泛。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/388544.html
