flutter开发多端平台应用的探索 上(基本操作)

前言

Flutter 是一个跨平台的开发框架,它允许开发者使用相同的代码库来构建 iOS、Android、Web 和桌面应用程序。

最近想了想,自己一直在用flutter开发特定端的应用,但是对于其他端的端特性case,如桌面端的菜单、多窗口、鼠标事件,需要怎么处理还没什么概念,本文旨在简单探索这方面的内容。

正文

首先就是判断平台了,可以通过如下方式

import 'dart:io' show Platform;

void checkPlatform() {
  if (kIsWeb) {
    print('Running on the web.');
  } else {
    if (Platform.isAndroid) {
    print('Running on Android.');
  } else if (Platform.isIOS) {
    print('Running on iOS.');
  } else if (Platform.isLinux) {
    print('Running on Linux.');
  } else if (Platform.isMacOS) {
    print('Running on macOS.');
  } else if (Platform.isWindows) {
    print('Running on Windows.');
  }
  }
}

手机端权限管理

这里flutter似乎是把这个事交给社区插件来做了,最著名的是permission_handler插件,原理后面探讨,大致用法如下

import 'package:permission_handler/permission_handler.dart';

Future requestPermissions() async {
  var status = await Permission.camera.status;
  if (!status.isGranted) {
    await Permission.camera.request();
  }

  status = await Permission.location.status;
  if (!status.isGranted) {
    await Permission.location.request();
  }
}

硬件特性

这个是谷歌官方已经为我们抽象出来了用法,比如摄像头有cameraController

import 'package:camera/camera.dart';

List? cameras;

Future main() async {
  cameras = await availableCameras();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CameraApp(),
    );
  }
}

class CameraApp extends StatefulWidget {
  @override
  _CameraAppState createState() => _CameraAppState();
}

class _CameraAppState extends State {
  CameraController? controller;

  @override
  void initState() {
    super.initState();
    controller = CameraController(cameras![0], ResolutionPreset.medium);
    controller!.initialize().then((_) {
      if (!mounted) {
        return;
      }
      setState(() {});
    });
  }

  @override
  void dispose() {
    controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (!controller!.value.isInitialized) {
      return Container();
    }
    return AspectRatio(
      aspectRatio: controller!.value.aspectRatio,
      child: CameraPreview(controller!),
    );
  }
}

监听键盘快捷键

如下demo是监听Ctrl+S这个快捷键的示例

具体来说就是需要LogicalKeySet来接受LogicalKeyboardKey的键盘快捷键,并且使用Shortcuts 小部件来设置快捷键与意图SaveIntent之间的映射关系,意图内部就是保存的具体操作,然后Actions 小部件来定义当某个意图发生时应该执行的动作,需要注意的是shortcuts组件只会监听当前具有焦点的小部件的快捷键事件,所以我们用一个focus包裹并设置autofocus为true,构建时候获取焦点。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ShortcutKeysApp(),
    );
  }
}

class ShortcutKeysApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Shortcuts(
      shortcuts: {
        LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyS): SaveIntent(),
      },
      child: Actions(
        actions: {
          SaveIntent: SaveAction(),
        },
        child: Focus(
          autofocus: true,
          child: Builder(
            builder: (context) {
              return ElevatedButton(
                onPressed: () {
                  SaveIntent().dispatch(context);
                },
                child: Text('Save'),
              );
            },
          ),
        ),
      ),
    );
  }
}

class SaveIntent extends Intent {
  const SaveIntent();
}

class SaveAction extends Action {
  @override
  Object? invoke(covariant SaveIntent intent) {
    // Implement
    print('Save action invoked');
    return null;
  }
}

监听鼠标事件

这个比较简单,用Listener就可以了

  • onPointerDown: 当用户按下鼠标按钮或触摸屏幕时触发。
  • onPointerMove: 当用户移动鼠标或手指时触发。
  • onPointerUp: 当用户释放鼠标按钮或移开手指时触发。
import 'package:flutter/material.dart';

class MouseEventsWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Listener(
      onPointerDown: (event) {
        print('Pointer down at: ${event.position}');
      },
      onPointerMove: (event) {
        print('Pointer move at: ${event.position}');
      },
      onPointerUp: (event) {
        print('Pointer up at: ${event.position}');
      },
      child: Container(
        width: 200,
        height: 200,
        color: Colors.blue,
        child: Center(
          child: Text('Do something with your mouse here'),
        ),
      ),
    );
  }
}

菜单

flutter目前是没有提供桌面菜单的原生支持的, 可以使用第三方插件如menubar 或 flutter_platform_menu_bar

import 'package:menubar/menubar.dart';

void setupMenu() {
  setApplicationMenu([
    Submenu(label: 'File', children: [
      MenuItem(label: 'New', onClicked: () => print('New clicked')),
      MenuItem(label: 'Open', onClicked: () => print('Open clicked')),
    ]),
    Submenu(label: 'Edit', children: [
      MenuItem(label: 'Undo', onClicked: () => print('Undo clicked')),
      MenuItem(label: 'Redo', onClicked: () => print('Redo clicked')),
    ]),
  ]);
}

多窗口

flutter没有提供多窗口支持,可以使用三方插件flutter_multi_window

import 'package:flutter_multi_window/flutter_multi_window.dart';

void openNewWindow() async {
  // 创建新的窗口
  await FlutterMultiWindow.createWindow('window_key');
}

// 处理来自其他窗口的消息
FlutterMultiWindow.setWindowCallback((message) {
  print('Received message: $message');
});

你可能感兴趣的:(flutter,设计模式,java,android)