Flutter Provide狀態管理基礎

http://www.lxweimin.com/p/cab2c1c2523f

Provide是Google官方推出的狀態管理模式。官方地址為:https://github.com/google/flutter-provide

現在Flutter的狀態管理方案很多,redux、bloc、state、Provide。

Scoped Model : 最早的狀態管理方案,我剛學Flutter的時候就使用的這個,雖然還有公司在用,但是大部分已經選用其它方案了。

Redux:現在國內用的最多,因為咸魚團隊一直在用,還出了自己fish redux。阿里宣布開源Flutter應用框架Fish Redux!

bloc:比Redux簡單,而且好用,特別是一個頁面里的狀態管理。

state:缺點是耦合太強,如果是大型應用,管理起來非常混亂。

Provide:是在Google的Github下的一個項目,剛出現不久,所以可以推測他是Google的親兒子。

要實現一個頁面狀態改變之后,另一個頁面狀態也隨之改變。效果圖如下:

效果圖

1、添加依賴

dependencies:

?provide: ^1.0.2


2、創建Provide

這個類似于創建一個state,但是為了跟State區分,我們叫創建Provide。新建一個provide文件夾,然后再里邊新建一個counter.dart 文件.代碼如下:

import 'package:flutter/material.dart';


class?Counter with ChangeNotifier {

?int value = 0;

?increment() {

?? ?value++;

?? ?notifyListeners();

?}

}


3、將狀態放入頂層

void main() {

?var counter =Counter();

?var providers = Providers();


? providers..provide(Provider<Counter>.value(counter));


?runApp(

?? ?ProviderNode(

????? child: MyApp(),

????? providers: providers,

?? ?)

?);


4、獲取狀態

class Number extends StatelessWidget {


?@override

? Widgetbuild(BuildContext context) {

?? ?return Container(

????? margin: EdgeInsets.only(top: 200.0),

????? child: Provide<Counter>(

??????? builder: (context, child,counter) {

???????? ?return Text('${counter.value}',style: TextStyle(fontSize: 30.0),);

?????? ?},

??? ??)

?? ?);

?}

}


builder方法接收三個參數

第一個參數context:代表上下文。

第二個參數child:假如這個小部件足夠復雜,內部有一些小部件是不會改變的,那么我們可以將這部分小部件寫在Provide的child屬性中,讓builder不再重復創建這些小部件,以提升性能。

第三個參數counter:這個參數代表了我們獲取的頂層providers中的狀態。

5、修改狀態

Widget build(BuildContext context) {

?? ?return Container(

????? child: Container(

??????? child: RaisedButton(

????????? onPressed: () {

??????????? Provide.value<Counter>(context).increment();

???????? ?},

????????? child: Text('增加'),

? ??????),

???? ?),

?? ?);

?}


項目地址

作者:zda123000

鏈接:http://www.lxweimin.com/p/cab2c1c2523f

來源:簡書

著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

bloc:Flutter 基于BLoC完整Flutter App項目

http://www.lxweimin.com/p/be0107298bc5

2019.01.11 00:22:32字數 501閱讀 15,656

本項目包含啟動頁,引導頁,主題色,國際化,Bloc,RxDart。擁有較好的項目結構,比較規范的代碼。App擁有精致的UI界面,統一的交互,側滑退出,列表和Web界面均提供快速滾動至頂部功能。

作者初衷是為大家提供一個比較規范的Flutter項目示例。

有關項目最新動態,可以關注App內第一條Hot Item信息。

App目錄結構

|--lib

|-- blocs (bloc相關)

|-- common (常用類,例如常量Constant)

|-- data (網絡數據層)

|-- db (數據庫)

|-- event (事件類)

|-- models (實體類)

|-- res (資源文件,string,colors,dimens,styles)

|-- ui (界面相關page,dialog,widgets)

|-- utils (工具類)

data網絡數據層

|--data

|-- api (url字段)

|-- net (單例DioUtil)

|-- protocol (請求與返回實體類)

|-- repository (接口請求&解析)

api

classWanAndroidApi{/// 首頁banner http://www.wanandroid.com/banner/jsonstaticconstString BANNER="banner";staticconstString USER_REGISTER="user/register";//注冊staticconstString USER_LOGIN="user/login";//登錄staticconstString USER_LOGOUT="user/logout";//退出// 拼接urlstaticStringgetPath({String path:'',int page,String resType:'json'}){StringBuffer sb=newStringBuffer(path);if(page!=null){sb.write('/$page');}if(resType!=null&&resType.isNotEmpty){sb.write('/$resType');}returnsb.toString();}}

請求與返回實體類 protocol

classLoginReq{String username;String password;LoginReq(this.username,this.password);LoginReq.fromJson(Map<String,dynamic>json):username=json['username'],password=json['password'];Map<String,dynamic>toJson()=>{'username':username,'password':password,};@overrideStringtoString(){StringBuffer sb=newStringBuffer('{');sb.write("\"username\":\"$username\"");sb.write(",\"password\":$password");sb.write('}');returnsb.toString();}}

接口請求&解析 repository

classWanRepository{Future<List<BannerModel>>getBanner()async{BaseResp<List>baseResp=awaitDioUtil().request<List>(Method.get,WanAndroidApi.getPath(path:WanAndroidApi.BANNER));List<BannerModel>bannerList;if(baseResp.code!=Constant.STATUS_SUCCESS){returnnewFuture.error(baseResp.msg);}if(baseResp.data!=null){bannerList=baseResp.data.map((value){returnBannerModel.fromJson(value);}).toList();}returnbannerList;}}

資源文件 res

|--res

|-- colors.dart

|-- dimens.dart

|-- strings.dart

|-- styles.dart

colors.dart

classColours{staticconstColor app_main=Color(0xFF666666);staticconstColor text_dark=Color(0xFF333333);staticconstColor text_normal=Color(0xFF666666);staticconstColor text_gray=Color(0xFF999999);}

dimens.dart

classDimens{staticconstdoublefont_sp12=12;staticconstdoublefont_sp14=14;staticconstdoublefont_sp16=16;staticconstdoublegap_dp5=5;staticconstdoublegap_dp10=10;}

strings.dart

classIds{staticconstString titleHome='title_home';}Map<String,Map<String,Map<String,String>>>localizedValues={'en':{'US':{Ids.titleHome:'Home',}},'zh':{'CN':{Ids.titleHome:'主頁',},'HK':{Ids.titleHome:'主頁',},'TW':{Ids.titleHome:'主頁',}}};

styles.dart

classTextStyles{staticTextStyle listTitle=TextStyle(fontSize:Dimens.font_sp16,color:Colours.text_dark,fontWeight:FontWeight.bold,);staticTextStyle listContent=TextStyle(fontSize:Dimens.font_sp14,color:Colours.text_normal,);staticTextStyle listExtra=TextStyle(fontSize:Dimens.font_sp12,color:Colours.text_gray,);}//? 間隔classGaps{// 水平間隔staticWidget hGap5=newSizedBox(width:Dimens.gap_dp5);staticWidget hGap10=newSizedBox(width:Dimens.gap_dp10);// 垂直間隔staticWidget vGap5=newSizedBox(height:Dimens.gap_dp5);staticWidget vGap10=newSizedBox(height:Dimens.gap_dp10);}

Flutter 國際化相關

fluintl?是一個為應用提供國際化的庫,可快速集成實現應用多語言。該庫封裝了一個國際化支持類,通過提供統一方法getString(id)獲取字符串。

// 在MyApp initState配置多語言資源setLocalizedValues(localizedValues);//配置多語言資源// 在MaterialApp指定localizationsDelegates和supportedLocalesMaterialApp(home:MyHomePage(),localizationsDelegates:[GlobalMaterialLocalizations.delegate,GlobalWidgetsLocalizations.delegate,CustomLocalizations.delegate//設置本地化代理? ? ],supportedLocales:CustomLocalizations.supportedLocales,//設置支持本地化語言集合? ? );// 字符串獲取IntlUtil.getString(context,Ids.titleHome);CustomLocalizations.of(context).getString(StringIds.titleHome);

Flutter 屏幕適配?ScreenUtil

方案一、不依賴context

步驟1//如果設計稿尺寸默認配置一致,無需該設置。? 配置設計稿尺寸 默認 360.0 / 640.0 / 3.0setDesignWHD(_designW,_designH,_designD);步驟2// 在MainPageState build 調用MediaQuery.of(context)classMainPageStateextendsState<MainPage>{@overrideWidgetbuild(BuildContextcontext){// 在 MainPageState build 調用 MediaQuery.of(context)MediaQuery.of(context);returnnewScaffold(appBar:newAppBar(),);}}步驟3ScreenUtil.getInstance().screenWidthScreenUtil.getInstance().screenHeight//屏幕適配相關? ScreenUtil.getInstance().getWidth(size);//返回根據屏幕寬適配后尺寸(單位 dp or pt)ScreenUtil.getInstance().getHeight(size);//返回根據屏幕高適配后尺寸 (單位 dp or pt)ScreenUtil.getInstance().getWidthPx(sizePx);//sizePx 單位pxScreenUtil.getInstance().getHeightPx(sizePx);//sizePx 單位pxScreenUtil.getInstance().getSp(fontSize);//返回根據屏幕寬適配后字體尺寸

方案二、依賴context

//如果設計稿尺寸默認配置一致,無需該設置。? 配置設計稿尺寸 默認 360.0 / 640.0 / 3.0setDesignWHD(_designW,_designH,_designD);ScreenUtil.getScreenW(context);//屏幕 寬ScreenUtil.getScreenH(context);//屏幕 高//屏幕適配相關? ScreenUtil.getScaleW(context,size);//返回根據屏幕寬適配后尺寸(單位 dp or pt)ScreenUtil.getScaleH(context,size);//返回根據屏幕高適配后尺寸 (單位 dp or pt)ScreenUtil.getScaleSp(context,size);//返回根據屏幕寬適配后字體尺寸

Flutter 數據存儲??SpUtil

SpUtil : 單例"同步" SharedPreferences 工具類。

項目中為大家提供SpHelper,方便存取實體對象類。

// 存儲SplashModel實體對象SplashModelmodel=newSplashModel();SpHelper.putObject(Constant.KEY_SPLASH_MODEL,model);// 獲取SplashModel實體對象SplashModelmodel=SpHelper.getSplashModel();classSpHelper{// 存儲Obj,T 用于區分存儲類型staticvoidputObject<T>(Stringkey,Objectvalue){switch(T){caseint:SpUtil.putInt(key,value);break;casedouble:SpUtil.putDouble(key,value);break;casebool:SpUtil.putBool(key,value);break;caseString:SpUtil.putString(key,value);break;caseList:SpUtil.putStringList(key,value);break;default:SpUtil.putString(key,value==null?"":json.encode(value));break;}}staticSplashModelgetSplashModel(){String_splashModel=SpUtil.getString(Constant.KEY_SPLASH_MODEL);if(ObjectUtil.isNotEmpty(_splashModel)){MapuserMap=json.decode(_splashModel);returnSplashModel.fromJson(userMap);}returnnull;}}

主界面

啟動頁

側滑Back

快速滾動到頂部

分類頁面

國際化

主題色

我的?????? :?Flutter開源庫集合

GitHub :?flutter_wanandroid

APK??????? :點擊下載 v0.1.3

Android掃碼下載APK:

flutter_wanandroid

最后,如果您覺得不錯的話,來個Star吧!大家對該項目有好的意見或建議,歡迎反饋。反饋-->

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,663評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,125評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,506評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,614評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,402評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,934評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,021評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,168評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,690評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,596評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,288評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,027評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,404評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,662評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,398評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,743評論 2 370

推薦閱讀更多精彩內容