伊始
前幾日一位大佬考我诈豌,說(shuō):
flutter頁(yè)面開(kāi)發(fā)需要寫(xiě)StatefulWidget和State仆救,Android只需要Activity,
如何簡(jiǎn)化這種開(kāi)發(fā)方式矫渔?
我答曰:
activity還需要寫(xiě)xml呢~
在大佬的靜默中,四周浮現(xiàn)起熱烈的掌聲......
......
深夜彤蔽,天橋下的我輾轉(zhuǎn)反側(cè)、難以入眠......
‘ 難道庙洼,真的可以顿痪? ’......
經(jīng)過(guò)反復(fù)推敲打磨后,這個(gè)‘輪子’還確實(shí)有點(diǎn)兒圓油够,‘滾’起來(lái)還挺順溜蚁袭。
天橋之下難免簡(jiǎn)陋,如有不足還請(qǐng)海涵石咬,萬(wàn)望指點(diǎn)~ 嘿嘿
構(gòu)思
我們一般開(kāi)發(fā)頁(yè)面A揩悄,結(jié)構(gòu)如下:
class A extends StatefulWidget{
}
class AState extends State<A>{
}
同時(shí)為了解耦和對(duì)路由統(tǒng)一做控制,我們采取的頁(yè)面跳轉(zhuǎn)方式(即靜態(tài)路由)是:
Navigator.of(context).pushName('/a')
此種跳轉(zhuǎn)方式的缺點(diǎn)就是頁(yè)面?zhèn)髦敌枰猰ap形式鬼悠,不方便的同時(shí)删性,還容易輸錯(cuò)Key,就算使用注解依然無(wú)法避免焕窝。
反復(fù)觀察和思考得出了下面這樣一張結(jié)構(gòu)圖
結(jié)構(gòu)圖
對(duì)各模塊做一下簡(jiǎn)單介紹
BaseState
abstract class BaseState<T extends StatefulWidget> extends State<T>{}
對(duì)page和view通用功能的封裝
WidgetState
abstract class WidgetState extends BaseState with WidgetGenerator{}
對(duì)自定義view的通用功能封裝
PageState
abstract class PageState extends BaseState with WidgetGenerator,RouteAware{}
對(duì)自定義Page的通用功能封裝
RouteAware對(duì)路由觀測(cè)蹬挺,你可以埋點(diǎn)或者記錄等等
WidgetGenerator
mixin WidgetGenerator on BaseState implements _RouteGenerator,_NavigateActor{}
生成widget并為widget裝配功能
_RouteGenerator 生成Route(可帶過(guò)渡動(dòng)畫(huà))功能
PageRoute<T> buildRoute<T>(Widget page, String routeName, {PageAnimation animation, Object args}) {
....
}
_NavigateActor 路由的各種push和pop操作,你也可以拓展
Future push<T extends PageState>(T page,{PageAnimation animation});
Future pushAndRemoveUntil<T extends PageState>(T page,{PageAnimation animation,RoutePredicate predicate});
Future pushReplacement<T extends Object,TO extends PageState>(TO page, {PageAnimation animation, T result });
void pop<T extends Object>({T result,});
void popUntil({RoutePredicate predicate});
bool canPop();
各模塊就介紹完畢了它掂,下面介紹一下使用方法巴帮。
如何使用
頁(yè)面的開(kāi)發(fā)
當(dāng)我們需要開(kāi)發(fā)頁(yè)面A時(shí),如下:
clas A extends PageState{
Widget build(BuildContext context){...}
}
就這么簡(jiǎn)單群发。
頁(yè)面?zhèn)髦?/h2>
當(dāng)我們想向B頁(yè)面?zhèn)饕粋€(gè)值/返回一個(gè)值到A頁(yè)面時(shí)晰韵,如下:
clas B extends PageState{
final var value;
B(this.value);
Widget build(BuildContext context){...}
}
A跳到B
A頁(yè)面內(nèi):push(B('你的值'))
.then((value)=>'B返回值=$value');
B退到A
B頁(yè)面內(nèi):pop(result:'返回給A的值');
pushAndRemoveUntil的使用
如果我從A到B到C发乔,然后C到D頁(yè)面的時(shí)候我想移除B和C熟妓,操作如下:
在C頁(yè)面
push(D(),predicate: (route)=>route.settings.name == '$A')
D頁(yè)面
當(dāng)你pop()后,你會(huì)發(fā)現(xiàn)到了A頁(yè)面
生成widget
我并不需要跳轉(zhuǎn)栏尚,但是需要將我的頁(yè)面/View生成widget,操作如下:
你的頁(yè)面/View.generateWidget({Key key}) 就可以生成一個(gè)widget了
如果需要key起愈,還可以加上一個(gè)
最后
我已經(jīng)將框架內(nèi)的Demo置換為現(xiàn)有的開(kāi)發(fā)方式,同時(shí)新增加了針對(duì)性的Demo并進(jìn)行了反復(fù)的測(cè)試译仗,總體來(lái)說(shuō)確實(shí)大幅度提升了開(kāi)發(fā)效率抬虽,避免了key值出錯(cuò)的問(wèn)題,另外在替換過(guò)程中也沒(méi)有遇到兼容性問(wèn)題纵菌,
不過(guò)這個(gè)依然算是初版阐污。
大家可以在下面的框架中使用,看看有啥不足或者bug告訴我咱圆,非常感謝笛辟。