Created
June 16, 2019 21:07
-
-
Save espresso3389/923cb2f3f24e834d166fc80b4c83cdcc to your computer and use it in GitHub Desktop.
Legend of Heroes
This file contains 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'; | |
/// The class controls every [Hero] widget has it's own name. | |
/// If the code generates [Hero.tag] by some model derived algorithm, | |
/// especially in list widgets such as [ListView.builder], the tag may | |
/// conflict in some case. The class has internal tag list and if same tag | |
/// is used twice, it does not insert [Hero] in that case. | |
/// ```dart | |
/// Widget build(BuildContext context) { | |
/// final heroInserter = HeroInserter(); | |
/// return .... | |
/// heroInserter.hero( | |
/// tag: 'aaaa', | |
/// child: const Text('aaaa') | |
/// ) | |
/// ... | |
/// } | |
/// ``` | |
class HeroInserter { | |
final _names = Set<String>(); | |
/// Insert [Hero] widget if same [tag] is never used. | |
Widget hero({String tag, Widget child}) { | |
if (!_names.add(tag)) | |
return child; | |
return Hero(tag: tag, child: child); | |
} | |
void clear() => _names.clear(); | |
} | |
/// The class prevents [Hero] tag duplications on [Widget] tree if you use | |
/// `LegendOfHeroes.of(context).hero` to insert [Hero] widgets. | |
/// ```dart | |
/// Widget build(BuildContext context) { | |
/// return LegendOfHeroes( | |
/// child: ... | |
/// ... | |
/// LegendOfHeroes.of(context).hero( | |
/// tag: 'some_name', | |
/// child: ... | |
/// ) | |
/// ); | |
/// } | |
/// ``` | |
class LegendOfHeroes extends StatefulWidget { | |
final Widget child; | |
LegendOfHeroes({@required this.child}); | |
@override | |
_LegendOfHeroesState createState() => _LegendOfHeroesState(); | |
/// Obtain [HeroInserter] held by the ancestor [LegendOfHeroes] widget. | |
static HeroInserter of(BuildContext context) { | |
final state = context.ancestorStateOfType(const TypeMatcher<_LegendOfHeroesState>()); | |
if (state is _LegendOfHeroesState) { | |
return state.inserter; | |
} | |
throw Exception('LegendOfHeroes is not found in the widget tree.'); | |
} | |
} | |
class _LegendOfHeroesState extends State<LegendOfHeroes> { | |
final inserter = HeroInserter(); | |
@override | |
Widget build(BuildContext context) { | |
inserter.clear(); | |
return widget.child; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment