Flutter (二十二) GlobalKey

0 阅读1分钟

GlobalKey

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

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

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),
      ),
    );
  }
}