Flutter视图控制器插件flutter_view_controller的使用
Flutter视图控制器插件flutter_view_controller的使用
复杂界面无需费力即可实现。可重用组件具有完全控制其状态和布局的能力。父母与子之间双向通信变得容易。用户界面更新可以直接从您的业务逻辑中进行。所有这些功能以及更多功能,均采用优雅简洁的语法。
目录
层级
控制器由子控制器组成,子控制器作为参数传递给相应的子视图。
app.dart
class AppController extends Controller {
ChildController child = ChildController();
[@override](/user/override)
onInit() {}
[@override](/user/override)
onClose() {}
}
class AppView extends ViewOf<AppController> {
const AppView({required super.controller});
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ChildView(controller: controller.child)
)
);
}
}
child.dart
class ChildController extends Controller {
[@override](/user/override)
onInit() {}
[@override](/user/override)
onClose() {}
}
class ChildView extends ViewOf<ChildController> {
const ChildView({required super.controller});
[@override](/user/override)
Widget build(BuildContext context) {
return Text("Child");
}
}
视图
视图部分负责构建布局。默认情况下,每个视图都是静态的。响应式通过通知器实现。
它可以用于整个页面或只是某个组件。每个视图都需要一个控制器,即使它不被使用。
view.dart
class ExampleView extends ViewOf<ExampleController> {
const ExampleView({required super.controller});
[@override](/user/override)
Widget build(BuildContext context) {
return Container(
height: 30,
width: 30,
color: Colors.red,
child: ...
);
}
}
控制器
Controller
类负责视图的行为。它包含视图的所有操作和属性,并且每个视图都有直接访问其对应控制器的方法。控制器包括方法和属性。
controller.dart
import 'package:flutter_view_controller/flutter_view_controller.dart';
class ExampleController extends Controller {
ButtonController _buttonController;
int counter = 0;
[@override](/user/override)
onInit(){
_configButtonController();
}
_configButtonController(){
_buttonController.onClick.then(incrementCounter);
}
incrementCounter(){
counter++;
}
[@override](/user/override)
onClose(){}
}
通知器
通知器对于Flutter视图控制器组件的状态管理至关重要。它们负责通知视图关于属性的变化。如果您有会影响布局的数据,则需要使用通知器。
您需要在控制器中声明通知器,并且所有通知器都必须有一个类型。
视图更新
您可以使用 show
方法在其变化时进行监听。要改变通知器的值,只需将其设置为新值。
app.dart
import 'package:flutter_view_controller/flutter_view_controller.dart';
class AppController extends Controller {
Notifier<String> message = Notifier("Default Message");
Notifier<int> number = Notifier(0);
[@override](/user/override)
onInit(){
message.value = "New message";
number.value++;
}
[@override](/user/override)
onClose(){}
}
class AppView extends View<AppController> {
AppView({required super.controller});
[@override](/user/override)
Widget build(BuildContext context) {
return Column(children:[
Container(
child: controller.message.show((snapshotMessage) => Text(snapshotMessage))
),
Container(
child: controller.number.show((snapshotNumber) => Text(snapshotNumber.toString()))
),
]);
}
}
监听控制器内的更改
您还可以在控制器内监听更改。
controller.dart
import 'package:flutter_view_controller/flutter_view_controller.dart';
class MessageController extends Controller {
Notifier<String> message = Notifier('Default Message');
[@override](/user/override)
onInit(){
message.listen((snapshotMessage) => print(snapshotMessage));
}
[@override](/user/override)
onClose(){}
}
连接通知器
您也可以连接到另一个通知器以传播更改。这在您有复杂的结构时非常有用。
child.dart
import 'package:flutter_view_controller/flutter_view_controller.dart';
class ChildController extends Controller {
Notifier<String> message = Notifier("Default Message");
[@override](/user/override)
onInit(){
// 这将在父消息更新时生效
message.listen((newMessage) => print(newMessage));
}
[@override](/user/override)
onClose(){}
}
parent.dart
import 'package:flutter_view_controller/flutter_view_controller.dart';
import 'child.dart';
class ParentController extends Controller {
ChildController child = ChildController();
Notifier<String> message = Notifier("Default Message");
[@override](/user/override)
onInit(){
message.connect(child.message);
message.value = "New message";
}
[@override](/user/override)
onClose(){}
}
通知列表
您还可以使用 NotifierList
在布局中创建反应式列表。NotifierList
目前仍处于早期阶段,但它已经具备了改变其反应性的必要方法。
app.dart
import 'package:flutter_view_controller/flutter_view_controller.dart';
class AppController extends Controller {
NotifierList<String> messages = NotifierList();
[@override](/user/override)
onInit(){}
addMessage(){
messages.add('Message');
}
[@override](/user/override)
onClose(){}
}
class AppView extends View<AppController> {
AppView({required super.controller});
[@override](/user/override)
Widget build(BuildContext context) {
return controller.messages.show((messages) =>
Column(
children:[
GestureDetector(
onTap: controller.addMessage,
child: Container(
child: Text('Add message')
),
),
...messages.map((message) => Text(message))
]
),
);
}
}
注意,show
方法返回一个单个的 Widget
,因为它始终返回一个 NotifierListener
。因此,要在列表中使用它,您需要将整个列表包裹在其中。之后,您可以按需展开项目。
无值的通知器
如果您想在不改变任何值的情况下通知某些事件,可以使用 NotifierTicker
。它可以通过所有通知器的功能生成脉冲。
然而,您不是向其添加新值,而是使用 tick()
方法触发它。此外,它的 show
方法不接受任何值。
app.dart
import 'package:flutter_view_controller/flutter_view_controller.dart';
class AppController extends Controller {
String message = 'Default Message';
NotifierTicker ticker = NotifierTicker();
[@override](/user/override)
onInit(){}
pulse(){
message = 'New Message';
ticker.tick();
}
[@override](/user/override)
onClose(){}
}
class AppView extends View<AppController> {
AppView({required AppController controller}) : super(controller: controller);
[@override](/user/override)
Widget build(BuildContext context) {
return controller.ticker.show(() =>
GestureDetector(
onTap: controller.pulse,
child: Container(
child: Text(controller.message)
),
),
);
}
}
NotifierTicker
用于内置的更新方法,该方法在所有受其控制的页面上刷新。
屏幕尺寸适配
为了简化小部件大小的计算,Flutter视图控制器在视图中带有一个内置属性。您可以随时访问屏幕宽度和高度,甚至可以根据视图计算百分比来调整组件的尺寸。
app.dart
import 'package:flutter_view_controller/flutter_view_controller.dart';
class AppView extends View<AppController> {
AppView({required AppController controller}) : super(controller: controller);
[@override](/user/override)
Widget build(BuildContext context) {
return Container(
height: size.height(55.2),
width: size.width(10),
...
)
}
}
更多关于Flutter视图控制器插件flutter_view_controller的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter视图控制器插件flutter_view_controller的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用flutter_view_controller
插件的示例代码。这个插件通常用于在原生iOS或Android应用中嵌入Flutter视图,并与之进行交互。
首先,确保你已经在pubspec.yaml
文件中添加了flutter_view_controller
依赖(尽管这个插件可能不直接存在,通常我们直接使用Flutter官方提供的嵌入机制,但这里为了说明概念,我们假设有这样一个插件)。不过,请注意,实际使用中,你可能需要使用的是Flutter Engine的嵌入API或其他相关插件。
dependencies:
flutter:
sdk: flutter
flutter_view_controller: ^x.y.z # 假设版本号存在,实际使用时替换为真实版本号
iOS端代码示例
在iOS项目中,你需要使用FlutterViewController
来嵌入Flutter视图。以下是一个简单的示例,展示如何在iOS的ViewController
中嵌入Flutter视图。
// ViewController.h
#import <UIKit/UIKit.h>
#import <Flutter/Flutter.h>
@interface ViewController : UIViewController
@end
// ViewController.m
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) FlutterViewController *flutterViewController;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 初始化Flutter引擎
FlutterEngine *flutterEngine = [[FlutterEngine alloc] initWithName:@"my_engine" project:nil];
// 创建并配置FlutterViewController
self.flutterViewController = [[FlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil];
self.flutterViewController.modalPresentationStyle = UIModalPresentationFullScreen;
// 将FlutterViewController作为当前视图控制器的子视图控制器
[self presentViewController:self.flutterViewController animated:YES completion:nil];
}
@end
Android端代码示例
在Android项目中,你需要使用FlutterActivity
或FlutterFragment
来嵌入Flutter视图。以下是一个使用FlutterActivity
的简单示例。
首先,确保在AndroidManifest.xml
中声明了FlutterActivity
:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="io.flutter.embedding.android.FlutterActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize" />
然后,在你的MainActivity
中启动FlutterActivity
:
// MainActivity.java
package com.example.myapp;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import io.flutter.embedding.android.FlutterActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 启动FlutterActivity
startActivity(
FlutterActivity
.withCachedEngine("my_engine_id")
.build(this)
);
}
}
注意,这里的withCachedEngine
方法需要你先在应用中创建并缓存一个Flutter引擎。这通常在你的应用启动时完成:
// Application.java
package com.example.myapp;
import android.app.Application;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterEngineCache;
import io.flutter.embedding.android.FlutterActivity;
public class Application extends android.app.Application {
@Override
public void onCreate() {
super.onCreate();
// 创建并缓存Flutter引擎
FlutterEngine flutterEngine = new FlutterEngine(this);
FlutterEngineCache
.getInstance()
.put("my_engine_id", flutterEngine);
}
}
Flutter端代码示例
在Flutter端,你可以像平常一样编写你的Dart代码。这部分代码将运行在嵌入的Flutter视图中。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter View Example'),
),
body: Center(
child: Text('Hello from Flutter!'),
),
),
);
}
}
请注意,上述代码是基于假设存在一个flutter_view_controller
插件的情况编写的。实际上,Flutter的嵌入机制通常使用FlutterEngine
和FlutterActivity
(Android)或FlutterViewController
(iOS)来完成。希望这些示例代码能帮助你理解如何在原生应用中嵌入Flutter视图。