mvp的全稱為Model-View-Presenter,Model提供數(shù)據(jù),View負(fù)責(zé)顯示,Controller/Presenter負(fù)責(zé)邏輯的處理。MVP與MVC有著一個(gè)重大的區(qū)別:在MVP中View并不直接使用Model,它們之間的通信是通過(guò)Presenter (MVC中的Controller)來(lái)進(jìn)行的,所有的交互都發(fā)生在Presenter內(nèi)部,
運(yùn)用在Flutter中
步驟一:編寫基類(base_presenter,base_state,base_view,lifecycle)
class BasePresenter<V extends BaseView>extends IPresenter{
V view;
CancelToken _cancelToken;
@override
void deactivatePresenter() {
}
@override
void disposePresenter() {
//請(qǐng)求取消
if(_cancelToken!=null){
if(_cancelToken.isCancelled){
_cancelToken.cancel();
}
}
}
@override
void initPresenter() {
}
}
abstract class BaseState<T extends StatefulWidget,V extends BasePresenter> extends State<T> implements BaseView{
V presenter;
V createPresenter();
BaseState() {
presenter = createPresenter();
presenter.view = this;
}
@override
BuildContext getContext() {
// TODO: implement getContext
return context;
}
bool _isShowDialog = false;
@override
void hideLoading() {
if (mounted && _isShowDialog){
_isShowDialog = false;
// NavigatorUtil.goBack(context);
}
}
@override
void showLoading() {
/// 避免重復(fù)彈出
if (mounted && !_isShowDialog){
_isShowDialog = true;
try{
showTransparentDialog(
context: context,
barrierDismissible: false,
builder:(_) {
return WillPopScope(
onWillPop: () async {
// 攔截到返回鍵,證明dialog被手動(dòng)關(guān)閉
_isShowDialog = false;
return Future.value(true);
},
child: const ProgressDialog(hintText:"加載中..."),
);
}
);
}catch(e){
/// 異常原因主要是頁(yè)面沒(méi)有build完成就調(diào)用Progress。
print(e);
}
}
}
@override
void showToast(String msg) {
BotToast.showText(text: msg);
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
presenter?.disposePresenter();
}
@override
void deactivate() {
// TODO: implement deactivate
super.deactivate();
presenter?.deactivatePresenter();
}
@override
void initState() {
// TODO: implement initState
super.initState();
presenter?.initPresenter();
}
}
abstract class BaseView{
BuildContext getContext();
//顯示加載loading
void showLoading();
//隱藏loading
void hideLoading();
//顯示吐司
void showToast(String msg);
}
//describe:周期管理
abstract class LifeCycle{
void initPresenter();
void deactivatePresenter();
void disposePresenter();
}
步驟二:在代碼中的運(yùn)用 以某個(gè)頁(yè)面為例
//我的頁(yè)面
class MinPage extends StatefulWidget {
@override
MinPageState createState() => MinPageState();
}
//mvp
class MinPageState extends BaseState<MinPage,MinPresenter> with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(
body: SingleChildScrollView(child:
Column(
children: buildLists(),
)
,),
);
}
List<Widget> buildLists(){
List<Widget> listWidgets=[];
listWidgets.add(MinTopWidget());
listWidgets.add(ThemeUtils.isDark(context)?Sps.hPureDark16:Sps.hPure16);
listWidgets.add(_buildShop());
listWidgets.add(ThemeUtils.isDark(context)?Sps.hPureDark16:Sps.hPure16);
listWidgets.add(MineItemsWidget());
return listWidgets;
}
Widget _buildShop(){
return Container(
height: ScreenAdapter.height(170),
child:InkWell(
child: Row(
children: <Widget>[
Sps.buildWGaps(32.0),
Expanded(
child:
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("多多積分信用商城",style: TextStyle(fontSize: ScreenAdapter.setSize(32),color: Color(0xFFF89F31)),),
Text("超多好禮等你兌換~",style: TextStyle(fontSize: ScreenAdapter.setSize(28),color:ThemeUtils.isDark(context)?Colors.white:Color(0x611D1D1C)))
],
),
),
Image.asset("assets/images/icon_min_shop.png",height: ScreenAdapter.height(48),width: ScreenAdapter.width(48),),
Icon(Icons.keyboard_arrow_right,size: ScreenAdapter.setSize(50),color: Color(0xFFA5AAB3),),
Sps.buildWGaps(32.0),
],
),
onTap: (){
BotToast.showText(text: "積分");
},
),
);
}
// Widget test(){
// Column(
// children: <Widget>[
// InkWell(
// child: Container( alignment: Alignment.center,height: ScreenAdapter.height(100), child: Text("深色模式")),
// onTap: (){
// //0表示淺色,1表示深色,2表示跟隨系統(tǒng)。
// ThemeMode themeMode = ThemeMode.dark ;
// /// 與上方等價(jià),provider 4.1.0添加的拓展方法
// context.read<ThemeProvider>().setTheme(themeMode);
// },
// ),
// InkWell(
// child: Container( alignment: Alignment.center,height: ScreenAdapter.height(100), child: Text("淺色模式")),
// onTap: (){
// ThemeMode themeMode = ThemeMode.light ;
// /// 與上方等價(jià),provider 4.1.0添加的拓展方法
// context.read<ThemeProvider>().setTheme(themeMode);
// },
// ),
// InkWell(
// child: Container( alignment: Alignment.center,height: ScreenAdapter.height(100), child: Text("跟隨系統(tǒng)")),
// onTap: (){
// ThemeMode themeMode = ThemeMode.system ;
// /// 與上方等價(jià),provider 4.1.0添加的拓展方法
// context.read<ThemeProvider>().setTheme(themeMode);
// },
// )
//
// ],
// )
// }
@override
MinPresenter createPresenter() {
// TODO: implement createPresenter
return MinPresenter();
}
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive =>true;
}
對(duì)應(yīng)的MinPresenter
class MinPresenter extends BasePresenter<MinPageState >{
var platform = const MethodChannel('com.guizhoudcb.anshun_app/md5');
//放一些網(wǎng)絡(luò)請(qǐng)求 數(shù)據(jù)庫(kù)操作
noticeData(pageindex, pageSize) async {
RealRepository.getInstance().realdata(pageindex, pageSize,8).then((onValue) {
//view.hideLoading();
if (onValue.status == 200) {
view.setData(onValue.data.records);
} else{
Toast.show(onValue.msg);
}
}, onError: (e) {
view.hideLoading();
});
}
@override
void initPresenter() {
// TODO: implement initPresenter
super.initPresenter();
}
}