Специфический случай использования VoidCallback

Специфический случай использования VoidCallback. Далее полный код

main.dart

import 'package:flutter/material.dart';

void main() async {
 runApp(MyApp());
}

class MyApp extends StatefulWidget {
 @override
 _MyAppState createState() => _MyAppState();
}

//класс 1
class _MyAppState extends State<MyApp> {
 //объявление переменных
 String _str;
 int _counter;

 //вызывается один раз при инициализации виджета
 @override
 void initState() {
  super.initState();
  _str = 'Hello World!';
  _counter = 0;
 }

 //тип возврата не указывается
 f1(String str) {
  setState(() {
   _counter++;
   if(_counter == 0) {
    _str = 'Привет Мир!';
    _counter = 1;
   } else {
    _str = 'Hello World!';
    _counter = 0;
   }
   str = _str;
  });
 }

 @override
 Widget build(BuildContext context) {
  return MaterialApp(
   debugShowCheckedModeBanner: false,
   home: MyHomePage(f1)
  );
 }
}

//класс 2
class MyHomePage extends StatelessWidget {
 String _str = '';
 final void Function(String) f1;
 //final VoidCallback f1;

 MyHomePage(this.f1);

 @override
 Widget build(BuildContext context) {
  return Scaffold(
   appBar: AppBar(
    title: Text('Name Page'),
   ),
   body: Stack(
    children: <Widget>[
     Align(
      alignment: Alignment.topLeft,
      child: Row(
       children: <Widget>[
        Expanded(
         flex: 1,
         child: Container(
          height: 40.0,
          margin: const EdgeInsets.all(10.0),
          child:  FlatButton(
           onPressed: () {
            f1(this._str);
           },
           shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(10.0)
           ),
           color: Colors.black26,
           child: Text(
            'Ok',
            style: TextStyle(
             color: Colors.white,
             fontSize: 20.0,
            ),
           ),
          ),
         ),
        ),
       ],
      ),
     ),
     Align(
      alignment: Alignment.center,
      child: Text(
       _str,
       style: TextStyle(
        color: Colors.pink,
        fontSize: 36.0
       ),
      ),
     ),
    ],
   ),
  );
 }
}

В //класс 1 создается метод f1 который будет принимать переменную из //класс 2 как аргумент и устанавливать и изменять ее значение. Но ничего не происходит. Так, как VoidCallback с параметром, то он был изменен на

final void Function(String) f1;

а значение ему передаются

onPressed: () {
 f1(this._str);
},

Но, ничего не происходит. Начальное значение текста не выводится и разумеется, текст не изменяется после нажатия кнопки. Спасибо.


Ответы (1 шт):

Автор решения: MiT

Ну так у вас Callback был void и ничего не возвращал, а также никому не присваивал свои значения.

import 'package:flutter/material.dart';

void main() async {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

//класс 1
class _MyAppState extends State<MyApp> {
  //объявление переменных
  String _str;
  int _counter = 0;

  //вызывается один раз при инициализации виджета
  @override
  void initState() {
    super.initState();
  }

  //тип возврата не указывается
  String f1(String str) {
    if (_counter == 0) {
      _str = 'Привет Мир!';
      _counter = 1;
    } else {
      _str = 'Hello World!';
      _counter = 0;
    }

    return _str;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MyHome(f1),
    );
  }
}

typedef MyCallback = String Function(String);

//класс 2
class MyHome extends StatefulWidget {
  final MyCallback f1;
  MyHome(this.f1);

  @override
  _MyHomepState createState() => _MyHomepState();
}

//класс 1
class _MyHomepState extends State<MyHome> {
  String _str = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Name Page'),
      ),
      body: Stack(
        children: <Widget>[
          Align(
            alignment: Alignment.topLeft,
            child: Row(
              children: <Widget>[
                Expanded(
                  flex: 1,
                  child: Container(
                    height: 40.0,
                    margin: const EdgeInsets.all(10.0),
                    child: FlatButton(
                      onPressed: () {
                        setState(() => _str = widget.f1(this._str));
                      },
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(10.0)),
                      color: Colors.black26,
                      child: Text(
                        'Ok',
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 20.0,
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
          Align(
            alignment: Alignment.center,
            child: Text(
              _str,
              style: TextStyle(color: Colors.pink, fontSize: 36.0),
            ),
          ),
        ],
      ),
    );
  }
}

UPD:

import 'package:flutter/material.dart';

void main() async {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

//класс 1
class _MyAppState extends State<MyApp> {
  //объявление переменных
  String _str = "";
  int _counter = 0;

  //вызывается один раз при инициализации виджета
  @override
  void initState() {
    super.initState();
  }

  //тип возврата не указывается
  void f1(String str) {
    if (_counter == 0) {
      setState(() {
        _str = 'Привет Мир!';
        _counter = 1;
      });
    } else {
      setState(() {
        _str = 'Hello World!';
        _counter = 0;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MyHome(f1, _str),
    );
  }
}

typedef MyCallback = void Function(String);

//класс 2
class MyHome extends StatelessWidget {
  final MyCallback f1;
  final String str;
  MyHome(this.f1, this.str);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Name Page'),
      ),
      body: Stack(
        children: <Widget>[
          Align(
            alignment: Alignment.topLeft,
            child: Row(
              children: <Widget>[
                Expanded(
                  flex: 1,
                  child: Container(
                    height: 40.0,
                    margin: const EdgeInsets.all(10.0),
                    child: FlatButton(
                      onPressed: () {
                        f1(str);
                      },
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(10.0)),
                      color: Colors.black26,
                      child: Text(
                        'Ok',
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 20.0,
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
          Align(
            alignment: Alignment.center,
            child: Text(
              str,
              style: TextStyle(color: Colors.pink, fontSize: 36.0),
            ),
          ),
        ],
      ),
    );
  }
}
→ Ссылка