当前位置: 首页 > article >正文

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<void> 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<CameraDescription>? cameras;

Future<void> 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<CameraApp> {
  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<SaveIntent> {
  @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');
});

http://www.kler.cn/a/292837.html

相关文章:

  • 浅谈:基于三维场景的视频融合方法
  • 【MySQL】约束
  • Java的dto,和多表的调用
  • request爬虫库的小坑
  • Oracle 11g rac 集群节点的修复过程
  • power bi中的related函数解析
  • Vue+Element多套主题切换
  • MLLM(一)| 文/图生视频任务大升级,BigModel 开源了视频模型CogVideoX
  • mysql开启远程访问
  • TCP/IP网络编程:第18章聊天室
  • 面向GPU计算平台的归约算法的性能优化研究
  • Rust 中 `madvise` 和 `posix_fadvise`的区别
  • python文件自动化(4)
  • 了解一下HTTP 与 HTTPS 的区别
  • FP7195:非同步升压恒流LED区动IC
  • C#实战|大乐透选号器[3]:动态生成大乐透蓝球区选择球及实现拖动窗体功能
  • Flask+LayUI开发手记(六):树型表格的增删改查
  • 网络编程 0905作业
  • 在ABAP开发中,BSEG和BKPF的数据如何做关联查询?
  • Unity(2022.3.41LTS) - UI详细介绍-TMP
  • WordPress的安装与简单开发教程
  • springboot 配置ssl支持https
  • 软通动力子公司鸿湖万联重磅发布SwanLinkOS 5,擘画开源鸿蒙AI PC新篇章
  • 七、装饰器模式
  • 薄膜制造革新-平扫式自动风环测厚仪
  • 基于 Python 的 LIF 模型:探索神经元同步与小世界网络