凯发娱发k8

flutter状态管理provider,简单上手 -凯发娱发k8

2023-10-18

在之前的文章中介绍了 google 官方仓库下的一个状态管理 provide。乍一看这俩玩意可能很容易就被认为是同一个东西,仔细一看,这不就差了一个字吗,有什么区别呢。

首先,你要知道的最大的一个区别就是,provide 被 provider 干掉了...假如你就是用了 provide 的,你的内心应该已经开始骂了,这不是坑爹吗 。不过幸运的是,你要从 provide 迁移到 provider 并不是太难。

provider 从名字上就很容易理解,它就是用于提供数据,无论是在单个页面还是在整个 app 都有它自己的凯发娱发k8的解决方案,我们可以很方便的管理状态。可以说,provider 的目标就是完全替代statefulwidget。

provider非全局状态管理:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; class homepage extends statelesswidget {
@override
widget build(buildcontext context) {
return scaffold(
appbar: appbar(
title: text('搜索结果'),
),
body: provider.value( //provider
value: 'this is from myhomepage',
child: myhomepage(),
),
);
}
} //provider.of
class myhomepage extends statelesswidget {
@override
widget build(buildcontext context) {
return center(
child: text('${provider.of(context)}'),
);
}
}
//consumer同样实现
class myhomepage extends statelesswidget {
@override
widget build(buildcontext context) {
return center(
//child: text('${provider.of(context)}'),
child:consumer(builder:(context, data, child){
return text(data);
}),
);
}
}

官方示例代码:

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; class counters with changenotifier {
int _count = ;
int get count => _count; void increment() {
_count ;
notifylisteners();
}
} class providerpage extends statelesswidget {
@override
widget build(buildcontext context) {
return multiprovider(
providers: [
changenotifierprovider(builder: (_) => counters()),
],
child: consumer(
builder: (context, counter, _) {
return materialapp(
supportedlocales: const [locale('en')],
localizationsdelegates: [
defaultmateriallocalizations.delegate,
defaultwidgetslocalizations.delegate,
_examplelocalizationsdelegate(counter.count),
],
home: const myhomepage(),
);
},
),
);
}
} class examplelocalizations {
static examplelocalizations of(buildcontext context) =>
localizations.of(context, examplelocalizations); const examplelocalizations(this._count); final int _count; string get title => 'tapped $_count times';
} class _examplelocalizationsdelegate
extends localizationsdelegate {
const _examplelocalizationsdelegate(this.count); final int count; @override
bool issupported(locale locale) => locale.languagecode == 'en'; @override
future load(locale locale) =>
synchronousfuture(examplelocalizations(count)); @override
bool shouldreload(_examplelocalizationsdelegate old) => old.count != count;
} class myhomepage extends statelesswidget {
const myhomepage({key key}) : super(key: key); @override
widget build(buildcontext context) {
return scaffold(
appbar: appbar(title: const title()),
body: const center(child: counterlabel()),
floatingactionbutton: const incrementcounterbutton(),
);
}
} class incrementcounterbutton extends statelesswidget {
const incrementcounterbutton({key key}) : super(key: key); @override
widget build(buildcontext context) {
return floatingactionbutton(
onpressed: () {
// `listen: false` is specified here because otherwise that would make
// `incrementcounterbutton` rebuild when the counter updates.
provider.of(context, listen: false).increment();
},
tooltip: 'increment',
child: const icon(icons.add),
);
}
} class counterlabel extends statelesswidget {
const counterlabel({key key}) : super(key: key); @override
widget build(buildcontext context) {
final counter = provider.of(context);
return column(
mainaxissize: mainaxissize.min,
mainaxisalignment: mainaxisalignment.center,
children: [
const text(
'you have pushed the button this many times:',
),
text(
'${counter.count}',
style: theme.of(context).texttheme.display1,
),
raisedbutton(
onpressed: (){
navigator.push(context, materialpageroute(builder: (context)=>providersecond()));
},
child: text('下一页'),
)
],
);
}
} class title extends statelesswidget {
const title({key key}) : super(key: key); @override
widget build(buildcontext context) {
return text(examplelocalizations.of(context).title);
}
}

class providersecond extends statelesswidget {
const providersecond({key key}) : super(key: key); @override
widget build(buildcontext context) {
final counter = provider.of(context);
return scaffold(
appbar: appbar(
leading: iconbutton( //返回按钮
onpressed: (){
navigator.pop(context); //返回上级页面
},
icon: icon(icons.arrow_back),
),
title: text('第二页'),
),
body: text(
'${counter.count}',
style: theme.of(context).texttheme.display1,
),
); }
}

效果图:

点击 到7,然后点击下一页,下一页的内容同样是7。

provider2.0到3.0的改变:

2.0:
changenotifierprovider.value(notifier: mynotifier), streamprovider(builder: (_) => streamcontroller()), 3.0:
changenotifierprovider.value(value: mynotifier), streamprovider.controller(builder: (_) => streamcontroller()),

 
下面基于provider v-3.0 写个简单的示例: 

第一步,添加provider依赖

provider: ^3.1. 

pub地址:https://pub.dev/packages/provider

第二步,创建model

class counter with changenotifier {
int _count = ;
int get count => _count; void increment() {
_count ;
notifylisteners();
}
}

简单的一个counters对象,里面只有一个字段_count

    这里需要混入changenotifier
    写一个增加的方法,然后需要调用notifylisteners();这个方法是通知用到counters对象的widget刷新用的。
    get方法

第三步,使用changenotifierprovider

我们要监听改变要在myapp()外面套一层,这个是全局的,于是代码如下 :

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import './provider/counter.dart'; void main() {
//runapp(new myapp());
runapp(
changenotifierprovider.value(//changenotifierprovider调用value()方法,里面传出value和child
value: counter(),//value设置了默认的counter()
child: myapp(),
)
);
}

当然provider不止提供了changenotifierprovider,还有provider、listenableprovider、valuelistenableproviderstreamprovider,
具体可以看wiki.
如果想管理多个对象可以用multiprovider,如下:

void main() {
//runapp(new myapp());
runapp(
// changenotifierprovider.value(//changenotifierprovider调用value()方法,里面传出value和child
// value: counter(),//value设置了默认的counter()
// child: myapp(),
// )
multiprovider(
providers: [
changenotifierprovider.value(value: counter()),
//changenotifierprovider(builder: (_) => counter()),
],
child: myapp(),
),
);
}

第四步,使用provider获取counter的值

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../provider/counter.dart'; class homepage extends statelesswidget {
@override
widget build(buildcontext context) {
return scaffold(
appbar: appbar(
title: text("home"),
actions: [
flatbutton(
child: text("下一页"),
onpressed: () =>
navigator.push(context, materialpageroute(builder: (context) {
return secondpage();
})),
),
],
),
body: center(
child: text("${provider.of(context).count}"),//用provider.of(context).count获取_count的值,provider.of(context)相当于provider去查找它管理的counter()
),
floatingactionbutton: floatingactionbutton(
onpressed: () {
provider.of(context).increment();//用provider.of(context).increment();调用counter()中的increment()方法
},
child: icon(icons.add),
),
);
}
}

同样第二个页面也这样写,如下

class secondpage extends statelesswidget {
@override
widget build(buildcontext context) {
var counter = provider.of(context).count;
return scaffold(
appbar: appbar(
title: text("secondpage"),
),
body: center(
child: text("${counter}"),
//child: text("${provider.of(context).count}"),
),
floatingactionbutton: floatingactionbutton(
onpressed: () {
provider.of(context).increment();
},
child: icon(icons.add),
),
);
}
}

这样,当每个页面都点击 号按钮时,_count便会 1,同时通知并更新到使用它的地方。

完整代码写到一个页面,copy后可直接运行:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; main() {
runapp(changenotifierprovider.value(
value: counter(),
child: myapp(),
));
} class myapp extends statelesswidget {
@override
widget build(buildcontext context) {
return materialapp(
title: "provider",
home: homepage(),
);
}
} class counter with changenotifier {//混入changenotifier
int _count = ;
get count => _count; void increment() {
_count ;
notifylisteners();//通知
}
} class homepage extends statelesswidget {
@override
widget build(buildcontext context) {
return scaffold(
appbar: appbar(
title: text("home"),
actions: [
flatbutton(
child: text("下一页"),
onpressed: () =>
navigator.push(context, materialpageroute(builder: (context) {
return secondpage();
})),
),
],
),
body: center(
child: text("${provider.of(context).count}"),//用provider.of(context).count获取_count的值,provider.of(context)相当于provider去查找它管理的counter()
),
floatingactionbutton: floatingactionbutton(
onpressed: () {
provider.of(context).increment();//用provider.of(context).increment();调用counter()中的increment()方法
},
child: icon(icons.add),
),
);
}
} class secondpage extends statelesswidget {
@override
widget build(buildcontext context) {
var counter = provider.of(context).count;
return scaffold(
appbar: appbar(
title: text("secondpage"),
),
body: center(
child: text("${counter}"),
//child: text("${provider.of(context).count}"),//1
),
floatingactionbutton: floatingactionbutton(
onpressed: () {
provider.of(context).increment();//
},
child: icon(icons.add),
),
);
}
}

效果图:

flutter状态管理provider,简单上手的相关教程结束。

网站地图