Flutter - 如何提取内部带有 onPressed setState 的 Widget?

Pen*_*bra 4 widget android-studio flutter

我想从内部提取一个小部件onPressed setState,但收到消息“无法提取对封闭类方法的引用。 ”有没有办法做到这一点?

我想将我的代码分成不同的小部件,以便保持清晰。这是代码的简化示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Calculator(),
    );
  }
}

class Calculator extends StatefulWidget {
  @override
  _CalculatorState createState() => _CalculatorState();
}

class _CalculatorState extends State<Calculator> {
  var myValue = 0;

  void calculate() {
    myValue = 12;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
            child: TextButton(
              onPressed: () {
                setState(() {
                  calculate();
                });
              },
              child: Text(
                'Button 001',
              ),
            ),
          ),
          TextOutput(myValue: myValue),
        ],
      ),
    );
  }
}

class TextOutput extends StatelessWidget {
  const TextOutput({
    Key key,
    @required this.myValue,
  }) : super(key: key);

  final int myValue;

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(
        myValue.toString(),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

我想提取到一个单独的小部件中的部分:

  Container(
    child: TextButton(
      onPressed: () {
        setState(() {
          calculate();
        });
      },
      child: Text(
        'Button 001',
      ),
    ),
  ),
Run Code Online (Sandbox Code Playgroud)

Fad*_*uad 5

Flutter 为子组件和父组件之间的回调式事件提供了 VoidCallback 和 Function(x)(其中 x 可以是不同的类型)。

简单地,您可以Function onPressed;通过构造函数传递这是您的提取容器小部件:

class ExtractedContainer extends StatelessWidget {
  final Function onPressed;
  const ExtractedContainer({
    Key key, @required this.onPressed,
  }) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Container(
      child: TextButton(
        onPressed: () {
          onPressed();
        },
        child: Text(
          'Button 001',
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

以及这里如何使用它:

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ExtractedContainer(onPressed: calculate,),
          TextOutput(myValue: myValue),
        ],
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

您的完整代码示例

import 'package:flutter/material.dart';

class MyApp2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Calculator(),
    );
  }
}

class Calculator extends StatefulWidget {
  @override
  _CalculatorState createState() => _CalculatorState();
}

class _CalculatorState extends State<Calculator> {
  var myValue = 0;

  void calculate() {
    myValue = 12;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ExtractedContainer(onPressed: calculate,),
          TextOutput(myValue: myValue),
        ],
      ),
    );
  }
}

class ExtractedContainer extends StatelessWidget {
  final Function onPressed;
  const ExtractedContainer({
    Key key, @required this.onPressed,
  }) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Container(
      child: TextButton(
        onPressed: () {
          onPressed();
        },
        child: Text(
          'Button 001',
        ),
      ),
    );
  }
}

class TextOutput extends StatelessWidget {
  const TextOutput({
    Key key,
    @required this.myValue,
  }) : super(key: key);

  final int myValue;

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(
        myValue.toString(),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)