我正在使用ImagePicker
和ImageCropper
插件,因此用户可以更改其当前的头像图片。当前头像是从NetworkImage
获得的Future
URL。当前头像上有一个按钮,允许用户从图库或他们的相机中选择并裁剪新图片。
这可以正常运行,但头像不会立即更新,并且需要热重启才能在此屏幕以及整个应用程序的其他屏幕上查看新照片。因此,我尝试将Provider
与ChangeNotifier
配合使用,以提醒Consumer
重建NetworkImage
。
但是我似乎找不到用Provider
来调用ChangeNotifier
的方法。这是我从Github获得的示例代码,我正在尝试重做;
class ImagePickerHandler {
ImagePickerDialog imagePicker;
AnimationController _controller;
ImagePickerListener _listener;
ImagePickerHandler(this._listener, this._controller);
openGallery(String currentuserid) async {
imagePicker.dismissDialog();
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
cropImage(image, currentuserid);
}
void init() {
imagePicker = ImagePickerDialog(this, _controller);
imagePicker.initState();
}
Future cropImage(File image, currentuserid) async {
var box = Hive.box('currentuser');
String newavatar = 'https://example.com/' + avatarpath ';
File croppedFile = await ImageCropper.cropImage(
sourcePath: image.path,
maxWidth: 500,
maxHeight: 500,
aspectRatio: CropAspectRatio(ratioX: 1.0, ratioY: 1.0),
);
_listener.userImage(croppedFile);
uploadAvatar(filepath:croppedFile.path);
box.put('currentavatar', newavatar );
}
showDialog(BuildContext context) {
imagePicker.getImage(context);
}
}
abstract class ImagePickerListener {
userImage(File _image);
}
理想情况下,我可以调用socialProvider.putBoxAvatar(newavavatar)
来代替box.put('currentavatar', newavatar )
,但由于它是方法而不是构建,所以我不能调用socialProvider
。
这是其中包含头像照片的版本;
class Picker extends StatefulWidget {
Picker({Key key, this.title}) : super(key: key);
final String title;
@override
_PickerState createState() => _PickerState();
}
class _PickerState extends State<Picker>
with TickerProviderStateMixin,ImagePickerListener{
File _image;
AnimationController _controller;
ImagePickerHandler imagePicker;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 500),
);
imagePicker= ImagePickerHandler(this,_controller);
imagePicker.init();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
var socialProvider = Provider.of<SocialProvider>(context);
return FutureBuilder(
future: Future.wait([socialProvider.loadCurrentAvatar()]),
builder: (context, snapshot) {
if (snapshot.hasData) {
return
SingleChildScrollView(
child: Container(
child: GestureDetector(
onTap: () => imagePicker.showDialog(context),
child: Center(
child: Stack(
children: <Widget>[
Center(
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 10, 20, 5),
child: Consumer<SocialProvider>(
builder: (context, socialProvider, child) {
return Image.network(snapshot.data[0],
width: 250,
height: 250,
);
}),
),
),
Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Container(
color: Colors.black26,
child: Icon(Icons.camera_alt,
color: Colors.white,
size: 40,
),
),
),
),
],
)
),
),
),
);
} else if(snapshot.hasError) {
return
Center(
child: Row(
children: <Widget>[
CircularProgressIndicator(),
FlatButton(onPressed: null, child: Text('reload'))
],
),
);
} else{
return Center(child: CircularProgressIndicator());
}
}
);
}
@override
userImage(File _image) {
setState(() {
this._image = _image;
});
}
}
这是我的带有更改通知程序的提供程序中提供的方法,该方法应提醒消费者。但是我在哪里可以打电话给putBoxAvatar(newavavatar)
?
String currentavatar;
putBoxAvatar(String boxavatar) {
var box = Hive.box('currentuser');
box.put('currentavatar', boxavatar);
currentavatar = boxavatar;
notifyListeners();
}
理想情况下,我可以代替socialProvider.putBoxAvatar(newavavatar)
来调用box.put('currentavatar', newavatar )
,但是由于它是方法而不是构建,所以我不能调用socialProvider
。