最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Flutter中mixin的使用詳解

 更新時(shí)間:2020年05月08日 09:28:54   作者:呀勒呀勒  
這篇文章主要介紹了Flutter中mixin的使用,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

mixin是什么

mixin應(yīng)該怎么理解呢,對(duì)Java系出身的我來(lái)說(shuō),這是一個(gè)新概念,各類資料的介紹也沒(méi)找到一個(gè)清晰的定義。從個(gè)人理解來(lái)看,可以把它想象為Kotlin中的接口(和Java的區(qū)別是可以帶非抽象的屬性和方法),而多個(gè)mixin可以相互覆蓋以實(shí)現(xiàn)組合,提供了非常大的靈活性,也可以達(dá)到類似多重繼承的效果。

頁(yè)表頁(yè)面

這是一個(gè)普通的展示數(shù)據(jù),上拉加載更多數(shù)據(jù)的列表。

其中有一個(gè)類型為List<T>的數(shù)據(jù)列表listData,有個(gè)page數(shù)據(jù)用于分頁(yè),isLoading用來(lái)判斷是否正在加載數(shù)據(jù),scrollController用于列表控制器

如果存在大量這種頁(yè)面則可以用mixin來(lái)處理,不免大量重復(fù)的代碼

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';

/// 列表頁(yè)面
class RecommendView extends StatefulWidget {
 @override
 _RecommendViewState createState() => _RecommendViewState();
}

class _RecommendViewState
 extends ListMoreDataBase<ListViewJsonData, RecommendView>
 with ListMoreDataMixin<ListViewJsonData, RecommendView> {
 @override
 Future<List<ListViewJsonData>> 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: <Widget>[
  NotificationListener<ScrollNotification>(
  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<T, K extends StatefulWidget> extends State<K> {
 /// 獲取異步數(shù)據(jù)
 Future<List<T>> getData();
}

/// 在
mixin ListMoreDataMixin<T, K extends StatefulWidget> on ListMoreDataBase<T, K> {
 @override
 void initState() {
 print('init');
 super.initState();
 initData();
 }

 @override
 void dispose() {
 print('dispose');
 super.dispose();
 scrollController?.dispose();
 }

 /// 數(shù)據(jù)列表
 List<T> listData = [];

 /// 分頁(yè)
 int page = 1;

 /// 是否在加載數(shù)據(jù)
 bool isLoading = false;

 /// 滾動(dòng)條控制器
 ScrollController scrollController = ScrollController();

 /// 初始化數(shù)據(jù)
 Future<void> initData() async {
 setState(() {
 isLoading = true;
 });

 List<T> data = await getData();
 if (!mounted) return;
 setState(() {
 listData = data;
 isLoading = false;
 });
 }

 /// 上拉加載更多
 Future<void> loadMore() async {
 setState(() {
 isLoading = true;
 page += 1;
 });

 List<T> 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是單繼承
  • 在類中,能重寫(xiě)mixin的屬性和方法,并且也能用super調(diào)用miixn屬性和方法
  • 上面的生命周期依次打印 init widget -> init -> dispose widget -> dispose

ps:下面從簡(jiǎn)單到復(fù)雜,演示mixin在Dart中的用法

最簡(jiǎn)單的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本身可以是抽象的,可以定義各種方法屬性,也可以是抽象的,等后續(xù)類去實(shí)現(xiàn)

基于某個(gè)類型的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
}

當(dāng)使用on關(guān)鍵字,則表示該mixin只能在那個(gè)類的子類使用了,那么結(jié)果顯然的,mixin中可以調(diào)用那個(gè)類定義的方法、屬性

多個(gè)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存在沖突的部分,后面會(huì)覆蓋前面的,沒(méi)有沖突的則會(huì)保留,所以可以存在后面的mixin修改了前面的mixin的一部分邏輯的情況,不需要直接繼承即可實(shí)現(xiàn)覆蓋,避免了更復(fù)雜的繼承關(guān)系

"多重繼承"
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
}

稍微有點(diǎn)繞,可以看到,這已經(jīng)事實(shí)上達(dá)到多重繼承才能達(dá)到的效果了,寫(xiě)起來(lái)比較麻煩,某種程度上也更不容易出錯(cuò)(相對(duì)于C++)。。。源碼里有最好也最復(fù)雜的例子—WidgetsFlutterBinding,它的定義如下:

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

具體WidgetsFlutterBinding的分析就沒(méi)啦,自己看源碼去吧~~

總結(jié)

到此這篇關(guān)于Flutter中mixin的使用的文章就介紹到這了,更多相關(guān)flutter mixin使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • Android開(kāi)發(fā)實(shí)現(xiàn)的簡(jiǎn)單計(jì)算器功能【附完整demo源碼下載】

    Android開(kāi)發(fā)實(shí)現(xiàn)的簡(jiǎn)單計(jì)算器功能【附完整demo源碼下載】

    這篇文章主要介紹了Android開(kāi)發(fā)實(shí)現(xiàn)的簡(jiǎn)單計(jì)算器功能,結(jié)合實(shí)例形式分析了Android計(jì)算器的具體實(shí)現(xiàn)步驟與相關(guān)操作技巧,并附帶完整demo源碼供讀者下載參考,需要的朋友可以參考下
    2017-11-11
  • Android中src和background的區(qū)別詳解

    Android中src和background的區(qū)別詳解

    這篇文章主要介紹了Android中src和background的區(qū)別詳解的相關(guān)資料,需要的朋友可以參考下
    2016-09-09
  • 解決Android Studio Gradle Metadata特別慢的問(wèn)題

    解決Android Studio Gradle Metadata特別慢的問(wèn)題

    這篇文章主要介紹了解決Android Studio Gradle Metadata特別慢的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-03-03
  • Android線程管理之ActivityThread

    Android線程管理之ActivityThread

    線程通信、ActivityThread及Thread類是理解Android線程管理的關(guān)鍵。通過(guò)本文給大家介紹Android線程管理之ActivityThread 的相關(guān)知識(shí),對(duì)android線程管理相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2016-01-01
  • android使用AIDL跨進(jìn)程通信(IPC)

    android使用AIDL跨進(jìn)程通信(IPC)

    本篇文章主要介紹了 android跨進(jìn)程通信(IPC):使用AIDL,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • Android自定義UI手勢(shì)密碼改進(jìn)版

    Android自定義UI手勢(shì)密碼改進(jìn)版

    這篇文章主要為大家詳細(xì)介紹了改進(jìn)版的Android自定義UI手勢(shì)密碼功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Android開(kāi)發(fā)之獲取LayoutInflater對(duì)象的方法總結(jié)

    Android開(kāi)發(fā)之獲取LayoutInflater對(duì)象的方法總結(jié)

    這篇文章主要介紹了Android開(kāi)發(fā)之獲取LayoutInflater對(duì)象的方法,結(jié)合實(shí)例形式總結(jié)分析了Android獲取LayoutInflater對(duì)象的常用技巧,需要的朋友可以參考下
    2016-02-02
  • 深入淺析Android JSON解析

    深入淺析Android JSON解析

    android中網(wǎng)絡(luò)數(shù)據(jù)傳輸是經(jīng)常被用到的,通常我們使用xml或者json,而json更加輕量,便捷,我們使用的更多。我自己在項(xiàng)目中使用很多,今天就說(shuō)說(shuō)android中怎么去解析JSON,幫助自己總結(jié)內(nèi)容,同時(shí)幫助別人少走彎路
    2015-12-12
  • Android Studio通過(guò)Artifactory搭建本地倉(cāng)庫(kù)優(yōu)化編譯速度的方法

    Android Studio通過(guò)Artifactory搭建本地倉(cāng)庫(kù)優(yōu)化編譯速度的方法

    這篇文章主要介紹了Android Studio通過(guò)Artifactory搭建本地倉(cāng)庫(kù)優(yōu)化編譯速度的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Android 聽(tīng)筒模式的具體實(shí)現(xiàn)實(shí)例

    Android 聽(tīng)筒模式的具體實(shí)現(xiàn)實(shí)例

    這篇文章主要介紹了Android 聽(tīng)筒模式的具體實(shí)現(xiàn)實(shí)例,有需要的朋友可以參考一下
    2013-12-12

最新評(píng)論

菏泽市| 辽阳县| 宜丰县| 宕昌县| 商水县| 漳平市| 古丈县| 昌宁县| 江川县| 康平县| 瑞丽市| 勃利县| 山西省| 苏尼特右旗| 文化| 夹江县| 鞍山市| 襄樊市| 法库县| 湘乡市| 凉城县| 枞阳县| 茂名市| 临西县| 南昌市| 宜城市| 镇雄县| 新兴县| 光泽县| 图们市| 加查县| 达孜县| 扶沟县| 宁晋县| 汉源县| 遂昌县| 江北区| 大方县| 西城区| 武义县| 名山县|