Flutter空Widget组件 nil的使用_Flutter空组件nil

发布于 1周前 作者 eggper 最后一次编辑是 5天前 来自 Flutter

Flutter空Widget组件 nil的使用_Flutter空组件nil

nil插件信息

Build Pub Codecov

什么是Nil?

Nil 是一个简单的widget,用于在你想要显示“空”的时候添加到widget树中,并且对性能的影响最小。

为什么需要它?

有时候根据条件,我们希望不显示任何东西。通常当我们不能返回null时,我们会返回类似 const SizedBox() 这样的widget。

这样做虽然可以解决问题,但它会带来一些性能影响,因为 SizedBox 创建了一个 RenderObject。这个对象存在于渲染树中,并且即使屏幕上没有绘制任何内容,也会对其执行一些计算。

我们可以做得更好,创建一个不会创建 RenderObject 的widget,同时仍然有效。Nil widget就是为了满足这种需求而设计的。它只创建一个 Element 并在构建时不做任何事情。由于最优的使用方式是调用 const Nil(),因此它还提供了一个可以在任何地方使用的 nil 常量(即 const Nil())。

使用方法

import 'package:nil/nil.dart';

return Builder(
  builder: (_) {
    if (condition) {
      return const MyWidget();
    } else {
      return nil;
    }
  },
);

注意事项

此widget不适用于接受多个子widget的场景(例如 RowsColumns 等)。在这种情况下,最好的选择是不在列表中添加不需要显示的widget。此外,在这些情况下使用 Nil widget可能会导致意外结果。

示例代码

下面是一个完整的示例代码,展示了如何在Flutter应用中使用 Nil 插件:

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

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Nil example')),
      body: Center(
        child: Builder(
          builder: (_) {
            // 根据当前分钟数是否为偶数来决定显示MyWidget还是nil
            if (DateTime.now().minute.isEven) {
              return const MyWidget();
            } else {
              return nil;
            }
          },
        ),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  const MyWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 200,
      width: 200,
      color: Colors.red,
    );
  }
}

通过上述代码,你可以看到当时间的分钟数为偶数时,页面中央会显示一个红色方块;否则,页面将保持空白,没有任何额外的性能开销。这正是 Nil 插件的魅力所在——以最高效的方式实现条件渲染。


更多关于Flutter空Widget组件 nil的使用_Flutter空组件nil的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter空Widget组件 nil的使用_Flutter空组件nil的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter开发中,遇到未知功能插件(假设这里的“nil”指的是一个未定义或未找到的插件)时,通常我们需要谨慎处理,因为直接使用未定义的插件会导致编译错误或运行时异常。不过,如果你是在探索或开发一个新的插件功能,这里有一些基本的步骤和代码示例,可以帮助你开始这个过程。

步骤 1: 创建插件项目

首先,你需要创建一个Flutter插件项目。你可以使用Flutter命令行工具来完成这一步。

flutter create --template=plugin my_unknown_plugin
cd my_unknown_plugin

这将创建一个基本的插件项目结构,包括平台(iOS和Android)特定的代码文件。

步骤 2: 实现插件功能

假设你想探索并实现一个简单的功能,比如在iOS和Android上显示一个Toast消息。你需要在插件的iOS和Android代码中分别实现这个功能。

iOS 实现

ios/Classes/MyUnknownPlugin.m中,你可以添加如下代码:

#import "MyUnknownPlugin.h"
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>

@implementation MyUnknownPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
    FlutterMethodChannel* channel = [FlutterMethodChannel
                                      methodChannelWithName:@"my_unknown_plugin"
                                      binaryMessenger:[registrar messenger]];
    MyUnknownPlugin* instance = [[MyUnknownPlugin alloc] init];
    [channel setMethodCallHandler:[instance methodCallHandler]];
}

- (void)methodCallHandler:(FlutterMethodCall*)call result:(FlutterResult)result {
    if ([call.method isEqualToString:@"showToast"]) {
        NSString *message = call.arguments[@"message"];
        dispatch_async(dispatch_get_main_queue(), ^{
            UIViewController *viewController = [UIApplication sharedApplication].keyWindow.rootViewController;
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:message preferredStyle:UIAlertControllerStyleAlert];
            [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
            [viewController presentViewController:alert animated:YES completion:nil];
        });
        result(nil);
    } else {
        result(FlutterMethodNotImplemented);
    }
}
@end

Android 实现

android/src/main/kotlin/com/example/my_unknown_plugin/MyUnknownPlugin.kt中,你可以添加如下代码:

package com.example.my_unknown_plugin

import android.app.Activity
import android.content.Context
import android.widget.Toast
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result

class MyUnknownPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
  private lateinit var channel: MethodChannel
  private var context: Context? = null
  private var activity: Activity? = null

  override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPluginBinding) {
    channel = MethodChannel(flutterPluginBinding.binaryMessenger, "my_unknown_plugin")
    channel.setMethodCallHandler(this)
    context = flutterPluginBinding.applicationContext
  }

  override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
    if (call.method == "showToast") {
      val message = call.argument<String>("message")
      message?.let {
        Toast.makeText(context, it, Toast.LENGTH_SHORT).show()
      }
      result.success(null)
    } else {
      result.notImplemented()
    }
  }

  override fun onDetachedFromEngine(@NonNull binding: FlutterPluginBinding) {
    channel.setMethodCallHandler(null)
  }

  override fun onAttachedToActivity(binding: ActivityPluginBinding) {
    activity = binding.activity
  }

  override fun onDetachedFromActivityForConfigChanges() {
    activity = null
  }

  override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
    activity = binding.activity
  }

  override fun onDetachedFromActivity() {
    activity = null
  }
}

步骤 3: 在Flutter应用中使用插件

在你的Flutter项目中,添加对插件的依赖(通常是通过pubspec.yaml文件),然后你可以在你的Dart代码中调用这个插件的方法。

dependencies:
  flutter:
    sdk: flutter
  my_unknown_plugin:
    path: ../path/to/your/plugin

然后在你的Dart代码中:

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

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

class MyApp extends StatelessWidget {
  static const platform = MethodChannel('my_unknown_plugin');

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Demo Home Page'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: _showToast,
            child: Text('Show Toast'),
          ),
        ),
      ),
    );
  }

  Future<void> _showToast() async {
    try {
      await platform.invokeMethod('showToast', {'message': 'Hello from Flutter!'});
    } on PlatformException catch (e) {
      print("Failed to invoke: '${e.message}'.");
    }
  }
}

这段代码展示了如何在Flutter应用中调用你新创建的插件方法。注意,这里的platform.invokeMethod调用的是插件中定义的showToast方法。

通过上述步骤,你可以开始探索并实现Flutter插件的新功能。如果遇到“nil”或未定义的插件问题,通常是因为插件没有正确注册或导入,确保按照上述步骤正确设置和引用你的插件。

回到顶部