它主要有两种用法,一是让widget在Widget Tree发生大幅改动的时候仍然保留状态,二是像JavaScript里面getElementById那样查找某个元素并得到它的各种信息
根据Flutter GlobalKey源码分析用法
abstract class GlobalKey<T extends State<StatefulWidget>> extends Key {
/// Creates a [LabeledGlobalKey], which is a [GlobalKey] with a label used for
/// debugging.
///
/// The label is purely for debugging and not used for comparing the identity
/// of the key.
factory GlobalKey({ String? debugLabel }) => LabeledGlobalKey<T>(debugLabel);
/// Creates a global key without a label.
///
/// Used by subclasses because the factory constructor shadows the implicit
/// constructor.
const GlobalKey.constructor() : super.empty();
Element? get _currentElement => WidgetsBinding.instance.buildOwner!._globalKeyRegistry[this];
/// The build context in which the widget with this key builds.
///
/// The current context is null if there is no widget in the tree that matches
/// this global key.
BuildContext? get currentContext => _currentElement;
/// The widget in the tree that currently has this global key.
///
/// The current widget is null if there is no widget in the tree that matches
/// this global key.
Widget? get currentWidget => _currentElement?.widget;
/// The [State] for the widget in the tree that currently has this global key.
///
/// The current state is null if (1) there is no widget in the tree that
/// matches this global key, (2) that widget is not a [StatefulWidget], or the
/// associated [State] object is not a subtype of `T`.
T? get currentState {
final Element? element = _currentElement;
if (element is StatefulElement) {
final StatefulElement statefulElement = element;
final State state = statefulElement.state;
if (state is T) {
return state;
}
}
return null;
}
}
生成的global实例有以下三个参数,
currentWidget
一般用于显示传入子widget的数据
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
//写法1 定义 GlobalKey
final GlobalKey buttonKey = GlobalKey();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Counter App'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 使用 CounterButton,并传入 GlobalKey
CounterButton(fontSize:48,key: buttonKey),
SizedBox(height: 20),
// 在这里显示当前计数
ElevatedButton(
onPressed: () {
final fontsize =( buttonKey.currentWidget as CounterButton).fontSize;
print(fontsize);
},
child: Text('Increase Count'),
),
],
),
),
),
);
}
}
// CounterButton Widget,用于显示当前计数
class CounterButton extends StatefulWidget {
final fontSize;
// 接收 GlobalKey
const CounterButton({this.fontSize,Key? key}) : super(key: key);
@override
_CounterButtonState createState() => _CounterButtonState();
}
class _CounterButtonState extends State<CounterButton> {
int count = 0;
// 增加计数的方法
void increaseCount() {
setState(() {
count++;
});
}
showFontsize(){
print( widget.fontSize);
}
@override
Widget build(BuildContext context) {
return Text(
'Count: $count',
style: TextStyle(fontSize: 24),
);
}
}
currentState
返回的是与之绑定的state,且绑定的元素必须是StatefulElement,一般用于获取子widget()的数据或者方法
示例如下
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
//写法1 定义 GlobalKey 用于获取按钮的状态
final GlobalKey<_CounterButtonState> buttonKey = GlobalKey();
//写法2 不加类型,则在使用时需要断定其类型
// final buttonKey = GlobalKey();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Counter App'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 使用 CounterButton,并传入 GlobalKey
CounterButton(key: buttonKey),
SizedBox(height: 20),
// 在这里显示当前计数
ElevatedButton(
onPressed: () {
//写法1 当按钮被点击时,调用按钮的 increaseCount 方法
buttonKey.currentState?.increaseCount();
//写法2 ( buttonKey.currentState as _CounterButtonState ).increaseCount();
},
child: Text('Increase Count'),
),
],
),
),
),
);
}
}
// CounterButton Widget,用于显示当前计数
class CounterButton extends StatefulWidget {
// 接收 GlobalKey
const CounterButton({Key? key}) : super(key: key);
@override
_CounterButtonState createState() => _CounterButtonState();
}
class _CounterButtonState extends State<CounterButton> {
int count = 0;
// 增加计数的方法
void increaseCount() {
setState(() {
count++;
});
}
@override
Widget build(BuildContext context) {
return Text(
'Count: $count',
style: TextStyle(fontSize: 24),
);
}
}
currentContext
相当于获取了对应的Element,就是下面的context
Widget build(BuildContext context) {}
context可以获得如下信息
Theme.of(context) //获取主题
Navigator.push(context, route) //入栈新路由
Localizations.of(context, type) //获取Local
context.size //获取上下文大小
context.findRenderObject() //查找当前或最近的一个祖先RenderObject
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final GlobalKey buttonKey = GlobalKey();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Counter App'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 使用 CounterButton,并传入 GlobalKey
CounterButton(key: buttonKey),
SizedBox(height: 20),
// 在这里显示当前计数
ElevatedButton(
onPressed: () {
final size = (buttonKey.currentContext?.findRenderObject()
as RenderBox)
.size;
print(size);
},
child: Text('Increase Count'),
),
],
),
),
),
);
}
}
// CounterButton Widget,用于显示当前计数
class CounterButton extends StatefulWidget {
// 接收 GlobalKey
const CounterButton({Key? key}) : super(key: key);
@override
_CounterButtonState createState() => _CounterButtonState();
}
class _CounterButtonState extends State<CounterButton> {
int count = 0;
// 增加计数的方法
void increaseCount() {
setState(() {
count++;
});
}
@override
Widget build(BuildContext context) {
return Text(
'Count: $count',
style: TextStyle(fontSize: 24),
);
}
}
111