千家信息网

在Android中Flutter的mixin有什么用

发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,小编给大家分享一下在Android中Flutter的mixin有什么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!mixin是什么mixin应该怎么理解呢,对Java系出身的我来说
千家信息网最后更新 2025年02月02日在Android中Flutter的mixin有什么用

小编给大家分享一下在Android中Flutter的mixin有什么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

mixin是什么

mixin应该怎么理解呢,对Java系出身的我来说,这是一个新概念,各类资料的介绍也没找到一个清晰的定义。从个人理解来看,可以把它想象为Kotlin中的接口(和Java的区别是可以带非抽象的属性和方法),而多个mixin可以相互覆盖以实现组合,提供了非常大的灵活性,也可以达到类似多重继承的效果。

页表页面

这是一个普通的展示数据,上拉加载更多数据的列表。

其中有一个类型为List的数据列表listData,有个page数据用于分页,isLoading用来判断是否正在加载数据,scrollController用于列表控制器

如果存在大量这种页面则可以用mixin来处理,不免大量重复的代码

import 'package:flutter/material.dart';import 'package:flutter_app/app/model/ListViewJson.dart';import 'package:flutter_app/app/shared/api/api.dart';import 'package:dio/dio.dart';import 'dart:convert';import 'package:flutter_app/app/shared/mixins/list_more_data_mixin.dart';/// 列表页面class RecommendView extends StatefulWidget { @override _RecommendViewState createState() => _RecommendViewState();}class _RecommendViewState extends ListMoreDataBase with ListMoreDataMixin { @override Future> getData() async { String data = await DioUtils.postHttp( "api/getOneLevel", parameters: FormData.fromMap({ 'page': page, 'limit': '10', }), ); ListViewJson _json = ListViewJson.fromJson(json.decode(data)); return _json.data; } @override void initState() { print('init widget'); super.initState(); } @override void dispose() { print('dispose widget'); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: AppBar(title: Text('返回')), body: Stack( children: [  NotificationListener(  onNotification: onNotification,  child: ListView.builder(  controller: scrollController,  itemCount: listData.length,  itemBuilder: (BuildContext context, int index) =>   TeamListItem(listData[index]),  ),  ),  isLoading ? Center(child: CircularProgressIndicator()) : Container() ], ), ); }}

mixin

import 'package:flutter/material.dart';abstract class ListMoreDataBase extends State { /// 获取异步数据 Future> getData();}/// 在mixin ListMoreDataMixin on ListMoreDataBase { @override void initState() { print('init'); super.initState(); initData(); } @override void dispose() { print('dispose'); super.dispose(); scrollController?.dispose(); } /// 数据列表 List listData = []; /// 分页 int page = 1; /// 是否在加载数据 bool isLoading = false; /// 滚动条控制器 ScrollController scrollController = ScrollController(); /// 初始化数据 Future initData() async { setState(() { isLoading = true; }); List data = await getData(); if (!mounted) return; setState(() { listData = data; isLoading = false; }); } /// 上拉加载更多 Future loadMore() async { setState(() { isLoading = true; page += 1; }); List data = await getData(); if (data.isEmpty) { page--; } setState(() { listData.addAll(data); isLoading = false; }); } bool canLoadMore(ScrollNotification scroll) { return !isLoading && scroll.metrics.maxScrollExtent <= scrollController.offset; } bool onNotification(ScrollNotification scroll) { if (canLoadMore(scroll)) { loadMore(); } return true; }}

注:

  • dart是单继承

  • 在类中,能重写mixin的属性和方法,并且也能用super调用miixn属性和方法

  • 上面的生命周期依次打印 init widget -> init -> dispose widget -> dispose

ps:下面从简单到复杂,演示mixin在Dart中的用法

最简单的mixin

mixin TestMixin { void test() { print('test'); } int testInt = 1; void test2();} class Test with TestMixin { @override test2() { print('test2'); }}void main() { Test().test();  // test print(Test().testInt); // 1 Test().test2();  // test2}

mixin本身可以是抽象的,可以定义各种方法属性,也可以是抽象的,等后续类去实现

基于某个类型的mixin

class BaseObject { void method() { print('call method'); }}mixin TestMixin on BaseObject{ void test() { print('test'); } int testInt = 1; void test2() { method(); }} class Test extends BaseObject with TestMixin {} void main() { Test().test();  // test print(Test().testInt); // 1 Test().test2();  // call method}

当使用on关键字,则表示该mixin只能在那个类的子类使用了,那么结果显然的,mixin中可以调用那个类定义的方法、属性

多个mixin

mixin TestMixin { void test() { print('test'); }  int testInt = 1;  void test2();} mixin TestMixin2 { int testInt = 2;  void test3() { print('test3'); }} class Test with TestMixin, TestMixin2 { @override test2() { print('test2'); }} void main() { Test().test();  // test print(Test().testInt); // 2 Test().test2();  // test2 Test().test3();  // test3}

如果把TestMixin和TestMixin2的先后顺序改一下:

mixin TestMixin { void test() { print('test'); }  int testInt = 1;  void test2();} mixin TestMixin2 { int testInt = 2;  void test3() { print('test3'); }} class Test with TestMixin2, TestMixin { @override test2() { print('test2'); }} void main() { Test().test();  // test print(Test().testInt); // 1 Test().test2();  // test2 Test().test3();  // test3}

如果mixin存在冲突的部分,后面会覆盖前面的,没有冲突的则会保留,所以可以存在后面的mixin修改了前面的mixin的一部分逻辑的情况,不需要直接继承即可实现覆盖,避免了更复杂的继承关系

"多重继承"mixin TestMixin on BaseClass { void init() { print('TestMixin init start'); super.init(); print('TestMixin init end'); }} mixin TestMixin2 on BaseClass { void init() { print('TestMixin2 init start'); super.init(); print('TestMixin2 init end'); }} class BaseClass { void init() { print('Base init'); } BaseClass() { init(); }} class TestClass extends BaseClass with TestMixin, TestMixin2 {  @override void init() { print('TestClass init start'); super.init(); print('TestClass init end');  }} void main() { TestClass(); /// TestClass init start /// TestMixin2 init start /// TestMixin init start /// Base init /// TestMixin init end /// TestMixin2 init end /// TestClass init end}

稍微有点绕,可以看到,这已经事实上达到多重继承才能达到的效果了,写起来比较麻烦,某种程度上也更不容易出错(相对于C++)。。。源码里有最好也最复杂的例子-WidgetsFlutterBinding,它的定义如下:

class WidgetsFlutterBinding extends BindingBase with GestureBinding, ServicesBinding, SchedulerBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding {}

看完了这篇文章,相信你对"在Android中Flutter的mixin有什么用"有了一定的了解,如果想了解更多相关知识,欢迎关注行业资讯频道,感谢各位的阅读!

0