Flutter (二十二) GlobalKey

GlobalKey

通过给一个组件设置GlobalKey,则可以在任意位置对该组件进行操作。

比如让获取某个组件的位置信息,滚动到可见区域。

scala 复制代码
import 'dart:math' show Random;

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

void main(List<String> args) {
  runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

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

class _MyAppState extends State<MyApp> {
  final GlobalKey<_ChildWidgetState> _redKey = GlobalKey<_ChildWidgetState>();
  final GlobalKey<_ChildWidgetState> _blueKey = GlobalKey<_ChildWidgetState>();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('EasyRefresh 示例')),
      body: Container(
        color: Colors.amber,
        child: ListView(
          children: [
            ChildWidget(
              key: _redKey,
              color: Colors.red,
              title: "红色",
              actionKey: _blueKey,
            ),
            SizedBox(height: MediaQuery.of(context).size.height),
            ChildWidget(
              key: _blueKey,
              color: Colors.blue,
              title: "蓝色",
              actionKey: _redKey,
            ),
          ],
        ),
      ),
    );
  }
}

class ChildWidget extends StatefulWidget {
  Color _color;
  final String _title;
  final GlobalKey<_ChildWidgetState> _actionKey;
  ChildWidget({
    super.key,
    required this._color,
    required this._title,
    required this._actionKey,
  });

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

class _ChildWidgetState extends State<ChildWidget> {
  void changeToColor(Color color) {
    setState(() {
      widget._color = color;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: widget._color,
      height: 100,
      alignment: Alignment.center,
      child: GestureDetector(
        onTap: () {
          Color color = HSLColor.fromAHSL(
            1,
            Random().nextInt(360).toDouble(),
            0.5,
            0.5,
          ).toColor();
          widget._actionKey.currentState?.changeToColor(color);
          print('点击了');
          final buildContext = widget._actionKey.currentContext;
          if (buildContext != null) {
            ScaffoldMessenger.of(
              buildContext,
            ).showSnackBar(const SnackBar(content: Text('改变了对方颜色')));

            final renderBox = buildContext.findRenderObject() as RenderBox?;

            final size = renderBox!.size; // 对方的尺寸
            final offset = renderBox!.localToGlobal(Offset.zero); // 对方在屏幕的坐标
            print('对方尺寸: $size, 屏幕坐标: $offset');

            Scrollable.ensureVisible(
              buildContext,
              duration: const Duration(milliseconds: 300),
              curve: Curves.easeInOut,
            );
          }
        },
        child: Text(widget._title),
      ),
    );
  }
}
相关推荐
用户2181697049301 小时前
Flutter (二十一) 下拉刷新,加载更多
前端
IT_陈寒3 小时前
Python装饰器把我坑惨了,原来这样用才不掉链子
前端·人工智能·后端
程序员爱钓鱼3 小时前
Rust Associated Type关联类型详解:为Trait定义内部类型
前端·后端·rust
zh_xuan3 小时前
个人主页左侧菜单支持分组,以及菜单显示和隐藏
前端·javascript·css
Emily156853598707 小时前
Emerson 1C31129G03 Analog Input Module
java·开发语言·前端·plc·emerson·1c31129g03·input module
To_OC12 小时前
面试被问了三回三栏布局,这次我终于把 BFC 那层窗户纸捅破了
前端·css·面试
To_OC12 小时前
啃完 TS 工具类型我发现:Pick 和 Omit 原来就是一层窗户纸
前端·面试·typescript
风月说与山鬼13 小时前
三、大括号语法
前端·react.js