likes
comments
collection
share

Flutter微框架Nylo(二十):NyPage组件

作者站长头像
站长
· 阅读数 0

在本节中,我们将了解 NyPage组件。大多数 Flutter 项目需要创建页面,例如登录页面、仪表板页面、个人资料页面等。Nylo的 NyPage 类可帮助您使用更少的代码更快地构建 UI,让我们深入了解一下。

在终端中,如果您运行以下命令,它将为您创建一个新页面。

dart run nylo_framework:main make:page dashboard

新页面将在 resources/pages/ 中创建

resources/pages/dashboard_page.dart

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

class DashboardPage extends NyPage {

  static String path = '/dashboard';

  @override
  init() async {
    // 页面初始化
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Dashboard")
      ),
      body: SafeArea(
         child: Container(
             child: Text("Hello World") // UI
         ),
      ),
    );
  }
}

以下是一些需要注意的重要事项:

  • path 是页面的路由路径。例如 routeTo(Dashboard.path) ,您可以使用此路径导航到页面。
  • init 在创建页面时调用。可以使用此方法加载数据、在类中设置数据或执行任何其他初始化工作。
  • build 包含将显示在 UI 上的 Widget。

使用控制器

控制器是将业务逻辑与 UI 分离的好方法。

创建页面和控制器的最简单方法是在终端中运行以下命令。

dart run nylo_framework:main make:page dashboard -c
# 或者使用metro
metro make:page dashboard -c

新页面和控制器将在 resources/pages/ 和 app/controllers/ 中创建

这是它将为您生成的代码。

Controller - DashboardController

app/controllers/dashboard_controller.dart

import 'controller.dart';
import 'package:flutter/widgets.dart';

class DashboardController extends Controller {
  
  // 在这里添加变量、方法、函数

  construct(BuildContext context) {
    super.construct(context);

  }

  // Example method
  bool isProUser() {
    User user = Backpack.instance.auth();
    if (user.isPro) {
      return true;
    }
    return false;
  }
}

Page - DashboardPage

resources/pages/dashboard_page.dart

import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
import '/app/controllers/dashboard_controller.dart';

class DashboardPage extends NyPage<DashboardController> {

  static String path = '/dashboard';

  @override
  init() async {
    // initialize the page
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Dashboard")
      ),
      body: SafeArea(
         child: Container(
            child: InkWell(
              onTap: () {
                bool isProUser = controller?.isProUser(); // 调用控制器方法
                /// do something
              },
              child: Text("Subscribe") // UI
            )
         ),
      ),
    );
  }
}

您可以在此处了解有关控制器的更多信息

如何使用 NyPage

在本节中,我们将了解:

Flutter 应用程序通常需要从 API 加载数据、将数据从一个页面传递到另一个页面或初始化类。

使用 NyPage 时,我们将展示如何处理其中一些情况。

初始化数据

每个页面都有一个 init 在创建页面时调用的方法。

您可以使用此方法初始化数据、类等。

尽量不要在类中 NyPage 设置数据,而是使用控制器来设置数据、变量。

import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
import '/app/controllers/dashboard_controller.dart';
import 'package:firebase_core/firebase_core.dart';

class DashboardPage extends NyPage<DashboardController> {

  static String path = '/dashboard';

  @override
  init() async {
    /* Firebase示例
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    ); 
    */
  }

  Future<List<String>> _getFavouriteFood() async {
    await Future.delayed(Duration(seconds: 2));
    return ["Rice", "Pasta", "Burger"];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Text("Dashboard")
      ),
      body: SafeArea(
        child: NyListView(
            child: (BuildContext context, dynamic food) {
              return ListTile(
                  title: Text(food)
              );
            },
            data: _getFavouriteFood
        ),
      ),
    );
  }
}

从 API 加载数据

从 API 加载数据时,建议使用 API 服务。

首先,创建一个控制器,例如 DashboardController .

import 'package:flutter_app/app/networking/api_service.dart';
import 'package:flutter_app/bootstrap/helpers.dart';
import 'controller.dart';
import 'package:flutter/widgets.dart';

class DashboardController extends Controller {

  List<dynamic> jsonPlaceHolderData = [];

  construct(BuildContext context) {
    super.construct(context);

  }

  loadJsonPlaceHolderData() async {
    jsonPlaceHolderData = await api<ApiService>((request) => request.get("https://jsonplaceholder.typicode.com/posts"));
  }
} 

然后,在 NyPage使用控制器

import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
import '/app/controllers/dashboard_controller.dart';

class DashboardPage extends NyPage<DashboardController> { // uses DashboardController

  static String path = '/dashboard';

  @override
  init() async {

  }

  @override
  boot() async {
    await Future.delayed(Duration(seconds: 2));
    await controller?.loadJsonPlaceHolderData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Text("Dashboard")
      ),
      body: SafeArea(
        child: NyListView(
            child: (BuildContext context, dynamic data) {
              return ListTile(
                  title: Text(data['title'])
              );
            },
            data: () async {
              return controller?.jsonPlaceHolderData; // 控制器返回的数据
            }
        ),
      ),
    );
  }

  @override
  Widget loading(BuildContext context) {
    return Scaffold(
      body: loadingWidget, // 在页面加载时使用loading组件
    );
  }
}

在上面的示例中,您会注意到我们正在使用 boot 方法来加载数据。

boot方法允许您加载数据。当页面加载时,它将显示 loading 组件。

您可以覆盖它以自定义加载状态的外观。

将数据传递到不同的页面

您可以使用该 routeTo 方法将数据传递到不同的页面。

假设我们有两个页面,DashboardPage 和 ProfilePage。

我们希望从 DashboardPage 将数据传递到 ProfilePage。

/// Dashboard Page
import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
import '/app/controllers/dashboard_controller.dart';

class DashboardPage extends NyPage<DashboardController> {

  static String path = '/dashboard';

  @override
  init() async {

  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Text("Dashboard")
      ),
      body: SafeArea(
        child: Column(
          children: [
            InkWell(
              child: Text("Route To Profile"),
              onTap: () {
                routeTo(ProfilePage.path, data: {"name": "Anthony"});
              },
            )
          ],
        )
      ),
    );
  }
}
/// Profile Page
import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
import '/app/controllers/dashboard_controller.dart';

class ProfilePage extends NyPage {

  static String path = '/profile';

  @override
  init() async {
    dynamic data = controller?.data();
    NyLogger.debug(data); // {"name": "Anthony"}
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Text("Profile")
      ),
    );
  }
}

方法

NyPage 课程有一些很棒的功能可供您使用。

分别是:

你可以在你的 NyPage 中调用这些助手,让我们看一些例子。

刷新页面

可以通过调用该 refreshPage 方法刷新页面。

import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
import '/app/controllers/dashboard_controller.dart';

class DashboardPage extends NyPage<DashboardController> {

  static String path = '/dashboard';

  @override
  boot() async {
      await Future.delayed(Duration(seconds: 2));
      await controller?.loadProfileData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Dashboard"),
        actions: [
          IconButton(onPressed: () {
            refreshPage(); // 刷新页面. `boot`将被调用
          }, icon: Icon(Icons.refresh))
        ],
      ),
      body: SafeArea(
        child: Column(
          children: [
            // 组件...
          ],
        )
      ),
    );
  }
}

更新状态

也可以使用 refreshPage 方法上的 setState 参数来更新状态。

refreshPage(setState: () {
  // 更新状态
});

下面是一个示例。

import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';
import '/app/controllers/dashboard_controller.dart';

class DashboardPage extends NyPage<DashboardController> {

  static String path = '/dashboard';

  @override
  init() async {
    
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Text("Dashboard"),
        actions: [
          IconButton(onPressed: () {
            refreshPage(setState: () {
              controller?.name = "Josh"; // 更新状态中的变量
            });
          }, icon: Icon(Icons.refresh))
        ],
      ),
    );
  }
}

显示 Toast 通知

您可以通过调用以下方法之一来显示 Toast 通知:

  • showToastSuccess(description: "Welcome back")
  • showToastDanger(description: "Your card has expired")
  • showToastWarning(description: "That email is already taken")
  • showToastInfo(description: "5 new messages")

如果您想自定义通知的外观,请查看 resources/widgets/toast_notification_widget.dart 文件。

更改语言

可以通过调用 changeLanguage 方法来更改语言。

changeLanguage("en");

在此处阅读有关本地化的文档以了解更多信息。

验证

可以通过调用该 validate 方法来验证表单。

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

class DashboardPage extends NyPage {

  static String path = '/dashboard';

  @override
  init() async {

  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Text("Dashboard")
      ),
      body: SafeArea(
        child: InkWell(
          child: Text("Login"),
          onTap: _login,
        )
      ),
    );
  }

  _login() {
    String email = "anthony@mail.com";
    String password = "password1";

    validate(rules: {
      "email": "email",
      "password": r'regex:([0-9]+)' // password contains one number
    }, data: {
      "email": email,
      "password": password
    }, onSuccess: () {
      NyLogger.debug("Success!");
    });
  }
}

阅读此处有关验证的文档以了解更多信息。