Last active
August 30, 2025 08:53
-
-
Save chooyan-eng/65724fa29f05a7d10f6635d157d3b52c to your computer and use it in GitHub Desktop.
Demo for Flutter Tokyo #10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'package:flutter/material.dart'; | |
| void main() => runApp(MaterialApp(home: MoveBasicPage())); | |
| class MoveBasicPage extends StatefulWidget { | |
| const MoveBasicPage({super.key}); | |
| @override | |
| State<MoveBasicPage> createState() => MoveBasicPageState(); | |
| } | |
| final _key = GlobalKey(); | |
| class MoveBasicPageState extends State<MoveBasicPage> { | |
| int _itemCount = 1; | |
| bool _showPosition = false; | |
| Offset? _firstTilePosition; | |
| @override | |
| Widget build(BuildContext context) { | |
| return Scaffold( | |
| body: Center( | |
| child: Column( | |
| spacing: 8, | |
| mainAxisSize: MainAxisSize.min, | |
| children: List.generate( | |
| _itemCount, | |
| (index) => Stack( | |
| clipBehavior: Clip.none, | |
| children: [ | |
| Tile( | |
| index, | |
| key: index == 0 ? _key : null, | |
| onTap: () { | |
| setState(() { | |
| _showPosition = !_showPosition; | |
| }); | |
| }, | |
| ), | |
| if (_showPosition && index == 0) | |
| Positioned( | |
| left: 40, | |
| top: -8, | |
| child: Container( | |
| decoration: BoxDecoration( | |
| color: Colors.redAccent, | |
| borderRadius: BorderRadius.circular(4), | |
| ), | |
| padding: const EdgeInsets.symmetric( | |
| horizontal: 12, | |
| vertical: 6, | |
| ), | |
| child: Text( | |
| '(${_firstTilePosition!.dx}, ${_firstTilePosition!.dy})', | |
| style: Theme.of( | |
| context, | |
| ).textTheme.bodyMedium?.copyWith(color: Colors.white), | |
| ), | |
| ), | |
| ), | |
| ], | |
| ), | |
| ), | |
| ), | |
| ), | |
| floatingActionButton: FloatingActionButton( | |
| onPressed: () { | |
| setState(() { | |
| _itemCount++; | |
| }); | |
| WidgetsBinding.instance.addPostFrameCallback((timeStamp) { | |
| final renderObject = _key.currentContext?.findRenderObject(); | |
| if (renderObject is RenderBox) { | |
| setState(() { | |
| _firstTilePosition = renderObject.localToGlobal(Offset.zero); | |
| }); | |
| } | |
| }); | |
| }, | |
| child: const Icon(Icons.add), | |
| ), | |
| ); | |
| } | |
| } | |
| class Tile extends StatelessWidget { | |
| const Tile(this.index, {super.key, this.onTap}); | |
| final int index; | |
| final VoidCallback? onTap; | |
| @override | |
| Widget build(BuildContext context) { | |
| return GestureDetector( | |
| onTap: onTap, | |
| child: Container( | |
| margin: const EdgeInsets.symmetric(horizontal: 60), | |
| padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 60), | |
| decoration: BoxDecoration( | |
| color: Colors.grey[100], | |
| borderRadius: BorderRadius.circular(8), | |
| border: Border.all(color: Colors.grey[600]!), | |
| ), | |
| child: Center( | |
| child: Text( | |
| 'Item $index', | |
| style: Theme.of(context).textTheme.bodyLarge, | |
| ), | |
| ), | |
| ), | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment