繁体   English   中英

如何从无状态类中的 onPressed 调用 StatefulWidget 的方法?

[英]How to call method of StatefulWidget from onPressed which is in Stateless class?

我正在学习颤振,作为第一个应用程序,我选择制作一个计算器。 我已经设置好布局,现在我需要对数据进行一些处理。 问题的核心是我想在每次按下按钮时更改输出(即 StatefullWidget)。

这是我使用自定义小部件 OutputWindow 和 Numberlane 的 main.dart。

import 'package:flutter/material.dart';
import 'package:study_project/NumberLane.dart';
import 'NumberLane.dart';
import 'OutputWindow.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.

  var custom = OutputWindow();
  //Function f = custom.outputText;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            appBar: AppBar(
                centerTitle: true,
                title: const Text("calculator"),
                titleTextStyle: const TextStyle(
                  fontWeight: FontWeight.bold,
                  fontSize: 25,
                )),
            body: Column(
                //mainAxisAlignment: MainAxisAlignment.center,'
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  //textoutput
                  Expanded(child: OutputWindow()),
                  //input
                  Expanded(
                    child: NumberLane(4),
                  ),
                  Expanded(
                    child: NumberLane(3),
                  ),
                  Expanded(
                    child: NumberLane(2),
                  ),
                  Expanded(
                    child: NumberLane(1),
                  ),
                ])));
  }
}

Numberlane 只是为了使代码更具可读性,其唯一目的是用另一个自定义类 Button 填充行

import 'package:flutter/material.dart';
import 'Button.dart';

class NumberLane extends StatelessWidget {
  int positioning = 0;

  NumberLane(this.positioning);

  @override
  Widget build(BuildContext context) {
    if (positioning == 1) {
      return Row(
        //crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Expanded(child: Button(".")),
          Expanded(child: Button("0")),
          Expanded(child: Button("=")),
          Expanded(child: Button("/")),
        ],
      );
    } else if (positioning == 2) {
      return Row(
        //crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Expanded(child: Button("1")),
          Expanded(child: Button("2")),
          Expanded(child: Button("3")),
          Expanded(child: Button("+")),
        ],
      );
    } else if (positioning == 3) {
      return Row(
        //crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Expanded(child: Button("4")),
          Expanded(child: Button("5")),
          Expanded(child: Button("6")),
          Expanded(child: Button("-")),
        ],
      );
    } else if (positioning == 4) {
      return Row(
        //crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Expanded(child: Button("7")),
          Expanded(child: Button("8")),
          Expanded(child: Button("9")),
          Expanded(child: Button("*")),
        ],
      );
    } else {}
  }
}

问题来了。 我有我的 TextButtons,我需要从 onPressed 调用作为 StatefullWidget OutputWindow 属性的 outputText 方法。 理想情况下,我希望每次点击按钮时都更改 OutputWindow。

**按钮

import 'package:flutter/material.dart';
import 'OutputWindow.dart';

class Button extends StatelessWidget {
  String description;
  //final Function outputText;
  Button(this.description) {}

  @override
  Widget build(BuildContext context) {
    return Container(
        width: double.infinity,
        height: double.infinity,
        child: TextButton(
          onPressed: () => {/*****here********/ },
          style: TextButton.styleFrom(
              primary: const Color.fromARGB(255, 227, 100, 61)),
          child: Text(
            description,
            style: const TextStyle(color: Color.fromARGB(255, 235, 88, 43)),
          ),
        ));
  }
}

**输出窗口

import 'package:flutter/material.dart';
import 'package:study_project/Button.dart';
import 'NumberLane.dart';
import 'main.dart';

class OutputWindow extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState

    return OutputWindowState();
  }
}

class OutputWindowState extends State<OutputWindow> {
  String output = "0";

  void outputText(String write) {
    setState(() {
      if (output == "0" ||
          write == "." ||
          write == "+" ||
          write == "-" ||
          write == "*" ||
          write == "/" ||
          write == "=") {
        output = write;
      } else if (write != "." &&
          write != "+" &&
          write != "-" &&
          write != "*" &&
          write != "/" &&
          write != "=") {
        output += write;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Text(output,
        style: const TextStyle(
          fontWeight: FontWeight.bold,
          fontSize: 35,
          color: Colors.black87,
        ));
  }
}

我已经尝试导入所有包和文件,但仍然无法调用我的 OutputWindow 的方法和实例化并通过 Instance.method() 调用该方法。 我想到的另一件事是通过指向构造函数的指针传递函数,但这仅适用于小部件树,我无法将方法从 OutputWindow 获取到 main.dart。

非常感谢你的帮助。

我添加了一些代码,所以它会工作。

import 'package:flutter/material.dart';

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

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

String outputText = "";

class Home extends StatefulWidget {
  const Home({
    Key? key,
  }) : super(key: key);

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  String output = '';

  @override
  void initState() {
    super.initState();
    outputText = output;
  }


  changeOutut(String value) {
    outputText = value;
    setState(() {
      output = value;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            centerTitle: true,
            title: const Text("calculator"),
            titleTextStyle: const TextStyle(
              fontWeight: FontWeight.bold,
              fontSize: 25,
            )),
        body: Column(
            //mainAxisAlignment: MainAxisAlignment.center,'
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              //textoutput
              Expanded(
                  child: OutputWindow(
                output: output,
              )),
              //input
              Expanded(
                child: NumberLane(4, changeOutut),
              ),
              Expanded(
                child: NumberLane(3, changeOutut),
              ),
              Expanded(
                child: NumberLane(2, changeOutut),
              ),
              Expanded(
                child: NumberLane(1, changeOutut),
              ),
            ]));
  }
}

class NumberLane extends StatelessWidget {
  final int positioning;
  final dynamic changeOutut;
  const NumberLane(this.positioning, this.changeOutut, {Key? key})
      : super(key: key);

  add(String value) {
    changeOutut(outputText + value);
  }

  @override
  Widget build(BuildContext context) {
    if (positioning == 1) {
      return Row(
        //crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Expanded(child: Button(".",add)),
          Expanded(child: Button("0",add)),
          Expanded(child: Button("=",add)),
          Expanded(child: Button("/",add)),
        ],
      );
    } else if (positioning == 2) {
      return Row(
        //crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Expanded(child: Button("1",add)),
          Expanded(child: Button("2",add)),
          Expanded(child: Button("3",add)),
          Expanded(child: Button("+",add)),
        ],
      );
    } else if (positioning == 3) {
      return Row(
        //crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Expanded(child: Button("4",add)),
          Expanded(child: Button("5",add)),
          Expanded(child: Button("6",add)),
          Expanded(child: Button("-",add)),
        ],
      );
    } else if (positioning == 4) {
      return Row(
        //crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Expanded(child: Button("7",add)),
          Expanded(child: Button("8",add)),
          Expanded(child: Button("9",add)),
          Expanded(child: Button("*",add)),
        ],
      );
    } else {
      return SizedBox();
    }
  }
}

class Button extends StatelessWidget {
  final String description;
  final dynamic add;
  const Button(this.description,this.add, {Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
        width: double.infinity,
        height: double.infinity,
        child: TextButton(
          onPressed: () => {
            add(description),
          },
          style: TextButton.styleFrom(
              primary: const Color.fromARGB(255, 227, 100, 61)),
          child: Text(
            description,
            style: const TextStyle(color: Color.fromARGB(255, 235, 88, 43)),
          ),
        ));
  }
}

class OutputWindow extends StatelessWidget {
  final String output;
  const OutputWindow({Key? key, required this.output}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Text(output,
        style: const TextStyle(
          fontWeight: FontWeight.bold,
          fontSize: 35,
          color: Colors.black87,
        ));
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM