这篇文章主要讲解了如何使用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 ListMoreDataBaseextends 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
{
}看完上述内容,是不是对如何使用Flutter中的mixin有进一步的了解,如果还想学习更多内容,欢迎关注创新互联行业资讯频道。
网站名称:如何使用Flutter中的mixin
分享URL:http://www.jxjierui.cn/article/pohcsg.html


咨询
建站咨询
