これがmain.dart
import 'package:flutter/material.dart'; import './my_widget.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: HomePage(), ); } } class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { MyWidget myWidget; @override void initState() { super.initState(); myWidget = MyWidget(); } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, floatingActionButton: myWidget, body: Container( color: Colors.greenAccent, child: Align( alignment: Alignment.center, child: Row( children: [ RaisedButton( onPressed: () { myWidget.runAnimation( SnackBarType.TYPE1, () { print('Type1 pushed'); }, ); }, child: Text('Type1'), ), RaisedButton( onPressed: () { myWidget.runAnimation( SnackBarType.TYPE2, () { print('Type2 pushed'); }, ); }, child: Text('Type2'), ), RaisedButton( onPressed: () { myWidget.close(); }, child: Text('Close'), ), ], ), ), ), ); } }
こいつがMyWidget
のメソッドを使ってる
呼ばれるクラスmy_widget.dart
info: This class (or a class which this class inherits from) is marked as '@immutable', but one or more of its instance fields are not final: MyWidget.runAnimation, MyWidget.close (must_be_immutable at [jikken] lib/my_widget.dart:8)
ウゼー。
import 'package:flutter/material.dart'; enum SnackBarType { TYPE1, TYPE2, } class MyWidget extends StatefulWidget { Function runAnimation = null; Function close = null; MyWidget({Key key}) : super(key: key); @override _MyWidgetState createState() => _MyWidgetState(); } class _MyWidgetState extends State<MyWidget> with SingleTickerProviderStateMixin { _MyWidgetState(); AnimationController _animationController; String _message = ''; String _buttonText = ''; Function callback; double get _leftMargin => 16.0; double get _rightMargin => 16.0; @override void initState() { _animationController = AnimationController( vsync: this, duration: const Duration(milliseconds: 500), ); this.widget.close = _close; this.widget.runAnimation = (SnackBarType snackBarType, Function callback) { this._setParams(snackBarType); _animationController.forward(); setState(() { this.callback = callback; }); }; super.initState(); } @override void dispose() { _animationController.dispose(); super.dispose(); } @override void didChangeDependencies() { super.didChangeDependencies(); } void _close() { _animationController.reverse(); } _setParams(SnackBarType snackBarType) { switch (snackBarType) { case SnackBarType.TYPE1: setState(() { this._message = 'it is type1'; this._buttonText = 'type1 button'; }); break; case SnackBarType.TYPE2: setState(() { this._message = 'it is type2'; this._buttonText = 'type2 button'; }); break; } } @override Widget build(BuildContext context) { return SlideTransition( position: Tween<Offset>( begin: const Offset(0.0, 1.0), end: Offset.zero, ).animate( CurvedAnimation( parent: _animationController, curve: Curves.fastOutSlowIn, ), ), child: Container( width: MediaQuery.of(context).size.width, height: 128.0, child: Align( alignment: Alignment.bottomCenter, child: Stack( alignment: AlignmentDirectional.bottomEnd, children: [ Padding( padding: EdgeInsets.only( left: _leftMargin, right: _rightMargin, ), child: Container( width: MediaQuery.of(context).size.width, height: 120.0, child: Column( mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[ SizedBox(height: 12.0), Text( this._message, textAlign: TextAlign.center, ), RaisedButton( color: Colors.yellow, onPressed: () { this.callback(); }, child: Text( this._buttonText, ), ), ], ), decoration: BoxDecoration( borderRadius: BorderRadius.all( Radius.circular( 4.0, ), ), color: Colors.blue, ), ), ), Padding( padding: EdgeInsets.only( right: 6.0, bottom: 104.0, ), child: ClipOval( child: Material( child: InkWell( child: Container( width: 28, height: 28, child: // close Align( alignment: Alignment.center, child: const Icon(Icons.close), ), ), onTap: () { _animationController.reverse(); }, ), ), ), ) ], ), ), ), ); } }
runAnimation
close
メソッドをうまく変更したいよ
class MyWidget extends StatefulWidget { Function runAnimation = null; Function close = null; MyWidget({Key key}) : super(key: key); @override _MyWidgetState createState() => _MyWidgetState(); }
こいつらを
class MyWidget extends StatefulWidget { final _MyWidgetState state = _MyWidgetState(); void runAnimation(SnackBarType snackBarType, Function callback) { state.runAnimation(snackBarType, callback); } void close() { state.close(); } MyWidget({Key key}) : super(key: key); @override _MyWidgetState createState() => state; }
こうした!