Flutter兼容性绑定插件bindings_compatible的使用

Flutter兼容性绑定插件bindings_compatible的使用

介绍

bindings_compatible 是一个用于在不同版本的 Flutter 中提供兼容的绑定实例的插件。从 Flutter 2.13 开始,绑定(bindings)始终是非空的(non-nullable),这导致使用空安全操作符(null-aware operators)调用绑定实例时会报告 lint 警告。为了在不同版本的 Flutter 中保持兼容性,bindings_compatible 插件将这些绑定封装到单独的函数中,并忽略警告。

完整示例 Demo

以下是一个完整的示例项目,展示了如何使用 bindings_compatible 插件来确保代码在不同版本的 Flutter 中都能正常工作。

import 'package:bindings_compatible/bindings_compatible.dart';
import 'package:flutter/material.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(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  // 这个小部件是应用程序的主页,它是有状态的,意味着它有一个 State 对象
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    // 使用 bindings_compatible 提供的兼容性方法
    useGestureBinding();    // 使用手势绑定
    usePaintingBinding();   // 使用绘画绑定
    useRendererBinding();   // 使用渲染器绑定
    useSchedulerBinding();  // 使用调度器绑定
    useSemanticsBinding();  // 使用语义绑定
    useServicesBinding();   // 使用服务绑定
    useWidgetsBinding();    // 使用小部件绑定

    setState(() {
      // 调用 setState 告诉 Flutter 框架某些状态已更改,从而重新构建界面
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    // 每次调用 setState 时都会重新运行此方法
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

代码说明

  1. 导入 bindings_compatible:

    import 'package:bindings_compatible/bindings_compatible.dart';
    

    这行代码导入了 bindings_compatible 包,以便我们可以使用它提供的兼容性方法。

  2. 使用兼容性方法: 在 _incrementCounter 方法中,我们调用了 bindings_compatible 提供的多个兼容性方法:

    useGestureBinding();
    usePaintingBinding();
    useRendererBinding();
    useSchedulerBinding();
    useSemanticsBinding();
    useServicesBinding();
    useWidgetsBinding();
    

更多关于Flutter兼容性绑定插件bindings_compatible的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter兼容性绑定插件bindings_compatible的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter开发中,bindings_compatible 包主要用于处理平台特定的代码绑定,以确保在不同平台(如iOS和Android)上具有一致的API和行为。虽然 Flutter 本身已经提供了很多跨平台的功能,但在某些情况下,你可能需要直接访问平台特定的功能或API。这时,bindings_compatible 包就显得非常有用。

下面是一个简单的示例,展示了如何在Flutter中使用bindings_compatible来访问平台特定的功能。不过,需要注意的是,bindings_compatible 包本身并不直接提供API,而是通过dart:ui和其他平台通道机制来实现跨平台兼容性。因此,这里我们会结合MethodChannel来演示如何实现这一功能。

1. 设置Flutter项目

首先,确保你的Flutter项目已经创建并配置好。如果还没有,可以使用以下命令创建一个新的Flutter项目:

flutter create my_flutter_app
cd my_flutter_app

2. 在Dart代码中定义MethodChannel

lib目录下创建一个新的Dart文件,例如platform_bindings.dart,并在其中定义与平台通信的MethodChannel

import 'package:flutter/services.dart';

class PlatformBindings {
  static const MethodChannel _channel = MethodChannel('com.example.my_flutter_app/platform_bindings');

  // 定义一个方法来获取平台版本(这是一个示例,具体实现取决于平台端代码)
  static Future<String?> getPlatformVersion() async {
    final String? version = await _channel.invokeMethod('getPlatformVersion');
    return version;
  }
}

3. 在Android端实现MethodChannel

android/app/src/main/kotlin/.../MainActivity.kt(或Java目录下的相应文件)中添加对MethodChannel的响应。

package com.example.my_flutter_app

import android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity: FlutterActivity() {
    private val CHANNEL = "com.example.my_flutter_app/platform_bindings"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "getPlatformVersion") {
                result.success(android.os.Build.VERSION.RELEASE) // 返回Android版本作为示例
            } else {
                result.notImplemented()
            }
        }
    }
}

4. 在iOS端实现MethodChannel

ios/Runner/AppDelegate.swift中添加对MethodChannel的响应。

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    
    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
    let channel = FlutterMethodChannel(name: "com.example.my_flutter_app/platform_bindings", binaryMessenger: controller.binaryMessenger)
    channel.setMethodCallHandler {
      (call: FlutterMethodCall, result: @escaping FlutterResult) in
      if call.method == "getPlatformVersion" {
        let version = UIDevice.current.systemVersion
        result(version)
      } else {
        result(FlutterMethodNotImplemented)
      }
    }
    
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

5. 在Flutter界面中使用PlatformBindings

最后,在你的Flutter应用的界面中使用PlatformBindings来获取平台版本并显示。

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

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String? _platformVersion = 'Unknown';

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

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> _getPlatformVersion() async {
    String? version;
    // Platform messages may fail, so we use a try-catch block.
    try {
      version = await PlatformBindings.getPlatformVersion();
    } on PlatformException {
      version = 'Failed to get platform version.';
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;

    setState(() {
      _platformVersion = version;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Platform Version'),
        ),
        body: Center(
          child: Text('Running on: $_platformVersion\n'),
        ),
      ),
    );
  }
}

通过上述步骤,你已经创建了一个简单的Flutter应用,它使用MethodChannel与原生平台代码进行通信,并展示了如何在Flutter中处理平台特定的功能。尽管示例中并未直接使用bindings_compatible包,但这种方法是实现跨平台兼容性绑定的常用方式。

回到顶部