繁体   English   中英

Flutter Dart OOP 编程基础 - 从一个 ZA2F2ED4F8EBC2CBB4C21A29DC40AB6D1 到另一个的文本

[英]Flutter Dart OOP programming basics - text from one class to another

我对 Flutter非常陌生。 我已经学习了大量的教程......现在,我正在尝试构建自己的Calculator App 我在使用OOP 和 dart时遇到问题。

我已经为我的单页计算器应用程序构建了前端(UI)

在此处输入图像描述

以下是三个代码文件:

main.dart

import 'package:flutter/material.dart';
import 'calculator_button_layout.dart';
import 'calculator_button.dart';

void main() {
  runApp(MaterialApp(
    home: Home(),
  ));
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Magic Calculator"),
        elevation: 0.0,
        backgroundColor: Colors.grey[900],
        centerTitle: true,
      ),
      body: Container(
        color: Colors.grey[850],
        child: Column(
          mainAxisAlignment: MainAxisAlignment.end,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Expanded(
              child: Padding(
                padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
                child: Container(
                  //color: Colors.green,
                  child: Align(
                    alignment: Alignment.bottomRight,
                    child: Text(
                      "0",
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 38,
                      ),
                    ),
                  ),
                ),
              ),
            ),
            CalculatorButtonLayout()
          ],
        ),
      ),
    );
  }
}

计算器按钮.dart:

import 'package:flutter/material.dart';

    class CalculatorButton extends StatefulWidget {
      final String text;
      final Color color;
      final int flex;
    
      CalculatorButton({this.text, this.color, this.flex});
    
      @override
      _CalculatorButtonState createState() => _CalculatorButtonState();
    }
    
    class _CalculatorButtonState extends State<CalculatorButton> {
    
      @override
      Widget build(BuildContext context) {
        return Expanded(
          flex: this.widget.flex,
          child: TextButton(
            onPressed: () {},
            child: Container(
              margin: EdgeInsets.all(1),
              padding: EdgeInsets.symmetric(
                  vertical: (MediaQuery.of(context).size.height / 20)),
              color: this.widget.color,
              child: Center(
                  child: Text(this.widget.text,
                      style: TextStyle(
                        fontSize: 30,
                        color: Colors.white70,
                        fontWeight: FontWeight.bold,
                      ))),
            ),
          ),
        );
      }
    }

计算器按钮布局.dart

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

class CalculatorButtonLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: [
          Row(
            children: [
              CalculatorButton(
                text: "C",
                color: Colors.red[800],
                flex: 1,
              ),
              CalculatorButton(
                text: "+/-",
                color: Colors.red[800],
                flex: 1,
              ),
              CalculatorButton(
                text: "%",
                color: Colors.red[800],
                flex: 1,
              ),
              CalculatorButton(
                text: "/",
                color: Colors.red[900],
                flex: 1,
              ),
            ],
          ),
          Row(
            children: [
              CalculatorButton(
                text: "1",
                color: Colors.grey[900],
                flex: 1,
              ),
              CalculatorButton(
                text: "2",
                color: Colors.grey[900],
                flex: 1,
              ),
              CalculatorButton(
                text: "3",
                color: Colors.grey[900],
                flex: 1,
              ),
              CalculatorButton(
                text: "*",
                color: Colors.red[900],
                flex: 1,
              ),
            ],
          ),
          Row(
            children: [
              CalculatorButton(
                text: "4",
                color: Colors.grey[900],
                flex: 1,
              ),
              CalculatorButton(
                text: "5",
                color: Colors.grey[900],
                flex: 1,
              ),
              CalculatorButton(
                text: "6",
                color: Colors.grey[900],
                flex: 1,
              ),
              CalculatorButton(
                text: "+",
                color: Colors.red[900],
                flex: 1,
              ),
            ],
          ),
          Row(
            children: [
              CalculatorButton(
                text: "7",
                color: Colors.grey[900],
                flex: 1,
              ),
              CalculatorButton(
                text: "8",
                color: Colors.grey[900],
                flex: 1,
              ),
              CalculatorButton(
                text: "9",
                color: Colors.grey[900],
                flex: 1,
              ),
              CalculatorButton(
                text: "-",
                color: Colors.red[900],
                flex: 1,
              ),
            ],
          ),
          Row(
            children: [
              CalculatorButton(
                text: "0",
                color: Colors.grey[900],
                flex: 2,
              ),
              CalculatorButton(
                text: ",",
                color: Colors.grey[900],
                flex: 1,
              ),
              CalculatorButton(
                text: "=",
                color: Colors.red[900],
                flex: 1,
              ),
            ],
          ),
        ],
      ),
    );
  }
}

我的问题:


当我按下计算器上的按钮时,如何将this.widget.text作为字符串发送到main.dart中的Text() 我已经查看了与“如何在颤动中从一个 class 获取数据到另一个”相关的所有问题。 但是发现正在使用 Navigator.push() ......但问题是我的应用程序是单页机

有多种方法可以实现它。 问题是您必须更新calculatorButton按钮的main.dart ontapText()的值。

使用 setState 是一种选择。 但是由于你的calculatorButtonHome是两个单独的类,使用 setState 可能会很复杂。

我将使用 Provider 进行数据处理。

您可以从这里安装 package: https://pub.dev/packages/provider/install

在 pubspec.yaml 中获取pubspec.yaml

提供者会自动更新变量的值,而无需一次又一次地调用 build 方法。

基本上,您将创建一个新的 class,如下所示。

class TextValue with ChangeNotifier{
String inputvalue;

get getTextvalue => inputvalue;

void setTextValue(String value){
this.inputvalue = value;
notifyListener();
}

}

notifyListener()将通知所有小部件变量的值已更改并且您需要重建。 因此,每次您点击按钮并调用setTextValue(value)方法时,它都会在main.dart中重建text小部件,并且值将被更新。

为了使用它,您需要在 main 方法中创建一个提供程序。 Provider就像超类,它将数据传递给它的子类。 因此,为了在您的所有应用程序中传递数据,我们将MaterialApp包装在provider中,并使用我们的TextValue class 创建一个provider 像这样:

void main() {
  runApp(
ChangeNotifierProvider(
create: (context) => TextValue(),
child: MaterialApp(
    home: Home(),
  ),
),
);
}

ChangeNotifierProvider是用于通知值更改的提供程序类型。 你可以找到很多关于这个的教程。

现在如何调用此方法并获取main.dart中的更新值。

让我们首先检查如何调用此方法:

Caculator_button.dart

 Widget build(BuildContext context) {
    return Expanded(
      flex: this.widget.flex,
      child: TextButton(
        onPressed: () {
Provider.of<TextValue>(context, listen:false).setTextValue(this.widget.text);

},

这将调用提供者内部的方法。 并通知它的孩子。

现在如何使用这个值。

在容器内的 Main.dart

Container(
                  //color: Colors.green,
                  child: Align(
                    alignment: Alignment.bottomRight,
                    child: Text(
//call the getter using provider
                      Provider.of<TextValue>(context, listen: false).getTextvalue,
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 38,
                      ),
                    ),
                  ),
                ),

而已。 您还可以进一步使用提供providerconsumer小部件。 您可以在文档中找到它。

尽管有很多方法可以将信息从一个地方传输到另一个地方,但您的用例非常简单,因此我会向您推荐最简单的解决方案。

回调

您可以使用回调的力量。 这些只是在父级中声明并作为变量传递给子级的函数。 function 可以从子内部执行以操作父内部的数据。 你的解决方案是这样的。


创建回调

  1. calculator_button.dart中,添加另一个属性,如下所示:
final void Function(String) onPressed;
  1. TextButton 小部件的 onPressed内部,将文本值传递给它,如下所示:
onPressed: (){
 widget.onPressed(widget.text);
}

这会调用父级提供的 function,传递它的文本值,然后可以在我们的父级内部使用,即main.dart


传递回调

由于您已经重构了小部件,因此您必须通过多个构造函数将回调向下传递,这是不使用dependency injection的缺点之一。

  1. calculator_layout.dart中,我们将像之前一样创建一个属性:
final void Function(String) buttonCallback;
  1. 将此属性传递给每个按钮:
CalculatorButton(
    onPressed: buttonCallback,
    ...
),

声明回调

最后,我们将为回调提供主体,这是在父窗口小部件内部完成的。

  1. main.dart中,我们想要将文本更新为新字符串,因此我们需要将Home小部件转换为有状态小部件。

  2. 在 state 中创建一个变量来存储文本:

class _HomeState extends State<Home> { //<-- Convert to stateful like this
final displayText = "0"; //<-- Add this state variable
  1. 将 function 传递给CalculatorLayout
CalculatorLayout(
    buttonCallback:(text){ //<-- This is the text that the child(CalculatorButton) passes
    setState((){ //<--Rebuilds the home widget to display the updated text
        displayText += text; //<-- Joins the new text to the previous one
    });
  }
), 
  1. 最后在我们的Text小部件中显示文本
child: Text(
    displayText,
    ...
),

您会看到许多 flutter 小部件经常使用回调,并且在关卡单一时很有用。 但是正如你所看到的,这对于更大的应用程序可能会变得非常混乱,更好的方法是使用ProviderGetIt以及Notifier

暂无
暂无

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

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