万年素人からHackerへの道

万年素人がHackerになれるまで殴り書きするぜ。

  • ・資産運用おすすめ
    10万円は1000円くらい利益
    資産運用ブログ アセマネ
    • ・寄付お願いします
      YENTEN:YYzNPzdsZWqr5THWAdMrKDj7GT8ietDc2W
      BitZenny:ZfpUbVya8MWQkjjGJMjA7P9pPkqaLnwPWH
      c0ban:8KG95GXdEquNpPW8xJAJf7nn5kbimQ5wj1
      Skycoin:KMqcn7x8REwwzMHPi9fV9fbNwdofYAWKRo

    Flutterで別のクラスのメソッドを呼ぼうとすると「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」

    これが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;
    }

    こうした!