繁体   English   中英

如何在 Dart / Flutter 中使用另一个文件的函数?

[英]How to use Functions of another File in Dart / Flutter?

我有一个 Flutter 应用程序,我在其中使用了 flutter_web_view 包。 我在几个不同的文件上使用它,并且希望创建自己的文件,并在我的应用程序中的任何位置简单地引用 _launchwebview 函数,因为需要多行代码才能使其工作。 我知道如何引用文件和传递信息,而不是方法/函数。 这是课程代码...

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

class ShopClass extends StatefulWidget {
  @override
  ShopClassState createState() => new ShopClassState();
}

class ShopClassState extends State<ShopClass> {
  String _redirectedToUrl;
  FlutterWebView flutterWebView = new FlutterWebView();
  bool _isLoading = false;

  @override
  initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    Widget leading;
    if (_isLoading) {
      leading = new CircularProgressIndicator();
    }
    var columnItems = <Widget>[
      new MaterialButton(
          onPressed: launchWebViewExample, child: new Text("Launch"))
    ];
    if (_redirectedToUrl != null) {
      columnItems.add(new Text("Redirected to $_redirectedToUrl"));
    }
    var app = new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          leading: leading,
        ),
        body: new Column(
          children: columnItems,
        ),
      ),
    );
    return app;
  }


  void launchWebViewExample() {
    if (flutterWebView.isLaunched) {
      return;
    }

    flutterWebView.launch("https://apptreesoftware.com",
        headers: {
          "X-SOME-HEADER": "MyCustomHeader",
        },
        javaScriptEnabled: false,
        toolbarActions: [
          new ToolbarAction("Dismiss", 1),
          new ToolbarAction("Reload", 2)
        ],
        barColor: Colors.green,
        tintColor: Colors.white);
    flutterWebView.onToolbarAction.listen((identifier) {
      switch (identifier) {
        case 1:
          flutterWebView.dismiss();
          break;
        case 2:
          reload();
          break;
      }
    });
    flutterWebView.listenForRedirect("mobile://test.com", true);

    flutterWebView.onWebViewDidStartLoading.listen((url) {
      setState(() => _isLoading = true);
    });
    flutterWebView.onWebViewDidLoad.listen((url) {
      setState(() => _isLoading = false);
    });
    flutterWebView.onRedirect.listen((url) {
      flutterWebView.dismiss();
      setState(() => _redirectedToUrl = url);
    });
  }



  void reload() {
    flutterWebView.load(
      "https://google.com",
      headers: {
        "X-SOME-HEADER": "MyCustomHeader",
      },
    );
  }
}

如何在另一个类中使用launchWebViewExample

您可以仅使用该函数编写文件,例如:

测试.dart

void launchWebView () {
  print("1234");
}

然后像这样导入该文件:

main.dart

import "test.dart";

class _MyHomePageState extends State<MyHomePage> {
   @override
   Widget build(BuildContext context) {
       launchWebView();

它不是很干净,但你可以做到这一点。 或者,您可以使用具有静态方法的类,例如:

class test {
    static void foo() {
        print("1234");
    }
}

然后在您的代码中像这样调用它(导入后):

test.foo();

或者您可以在一个类中声明所有函数(帮助程序)并将它们作为参数传递给其他类。

//The class which contains your functions
class HelperFunction{

  //Define your method
  void launchWebView () {
    print("1234");
  }

  //Pass that function to a class
  MyHomePage(launchWebView);

}

//The class which receives the function.
class MyHomePage extends StatefulWidget{
  //Retrieve the function and store it to a variable of type Function.
  final Function launchWebView;
  MyHomePage(this.launchWebView);
}

class _MyHomePageState extends State<MyHomePage> {
   @override
   Widget build(BuildContext context) {
     //Access that function in State class using widget keyword.
     widget.launchWebView();
   }
}  

为什么会发生这种情况?

我在几个不同的文件上使用它,并且希望创建自己的文件并在我的应用程序中的任何位置使用 _launchwebview 函数进行引用,因为需要多行代码才能使其工作。

下划线方法是给定库的私有方法。 因此,如果我们在一个文件中定义_launchwebview ,那么该函数位于一个小型库 ( Source ) 中,因此只能在该文件中访问它。 在探索如何在不同文件中公开私有方法时,我认为使用公共函数会更好地回答这个问题。 问题是在不同的类中实现共享功能而不是简单地提供访问。

我选择为这个特定问题添加此解决方案,因为该方法(启动 Web 视图)最好在每个适当的Widget类中实现。 请注意,扩展方法也可以在这种情况下工作,但 Flutter 更喜欢组合而不是继承。

如果我们想在不复制粘贴的情况下将一个公共的,即非下划线的方法移动到一个不同的类,我们可以尝试几种概述的方法(见下文)。

黑客解决方案

  1. 使用part指令使我们能够使用私有实现复制一个文件的源,并在另一个文件中使用它。 但这是不鼓励的,因为该技术增加了二进制大小,违反了 Effective Dart 使用指南,并且不是一个优雅的解决方案。
  2. 使用全局函数不是好的面向对象编程,因为它们违反了封装原则。 最佳答案推荐了这种方法,我认为可以进一步改进答案。 我写这个答案是为了提供一个替代解决方案。
  3. 静态函数也打破了封装和开闭原则。 它们还使我们难以与状态管理解决方案集成,因为我们应该在实例方法上下文(如provider和其他知名包)中跟踪状态。

解决方案:混合

当我们想要减少重复代码但避免扩展整个类( Source )时,Dart 内置了对可选地向类添加函数的支持。 mixin关键字通过将类与某些特定逻辑混合并使用on将 mixin 限制为特定子类来实现这一点。

所以我们可以先在一个新文件中添加共享代码:

mixin LaunchWebView { // you can also constrain the mixin to specific classes using on in this line.
  void launchWebView() {
    // Add web view logic here. We can add variables to the mixin itself as well.
  }
}

然后在另一个文件中我们喜欢的任何地方使用它,如下所示:

class ExampleClass extends Musician with LaunchWebView {
  void testFunction() {
    // We now have access to launchWebView().
    launchWebView();
  }
}

你可以用不同的方式做到这一点:

1.全局功能:

在文件中定义你的函数,比如global.dart

void func() => print('Hello');

要在任何文件中使用它,只需调用:

func();

2.类中的静态函数:

创建一个类,说Foo并在其中定义您的函数:

class Foo {
  static void func() => print('Hello');
}

要在任何文件中使用它,只需调用

Foo.func();

3.使用mixin:

  • 如果要在任何类中使用该函数:

    创建一个 mixin,比如Bar

     mixin Bar { void func() => print('Hello'); }

    要在类中使用它,只需使用with关键字后跟 mixin。

     class Baz with Bar { void main() => func(); }
  • 如果要限制 mixin 与任何类一起使用:

     class Foo {}

    创建一个 mixin,比如在Foo上的Bar

     mixin Bar on Foo { void func() => print('Hello'); }

    要使用Bar mixin,我们需要扩展Foo类,因为它就是这样。

     class Baz extends Foo with Bar { void main() => func(); }

您想在类级别上声明函数

文件 foo.dart

class Foo {

  static void launchWebView () {};

}

文件 bar.dart

import 'foo.dart'
class Bar {

  void someFunction (){
    Foo.launchWebView();
  }


}

暂无
暂无

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

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