#flutter #dart #flutter-provider #flutter-image #flutter-change-notifier
#flutter #dart #flutter-provider #flutter-изображение #flutter-change-notifier
Вопрос:
Я использую Provider with ChangeNotifier
для оповещения Consumer
, когда новая фотография загружается на сервер, заменяя старую фотографию. Проблема в том, что URL-адрес остается тем же, поскольку фотография просто перезаписывается и сохраняет то же имя. Следовательно, потребитель не распознает, что что-то изменилось, и не обновляет старую фотографию новой.
Как я могу обмануть ChangeNotifier для обновления URL? Вот Consumer
в моей сборке;
Consumer<SocialProvider>(
builder: (context, socialProvider, child) {
return Image.network(socialProvider.currentavatar,
);
}),
Здесь изображение выбирается в галерее и загружается, чтобы перезаписать старое изображение на сервере.
GestureDetector(
onTap: () async {
await socialProvider.loadCurrentUserId();
await _listener.openGallery(socialProvider.currentuserid);
String updatedavatar = "http://example.com/same_photo.jpg";
socialProvider.updateAvatar(updatedavatar);
},
И вот код в поставщике с ChangeNotifier;
Future<void> updateAvatar(String avatar) async {
var box = await Hive.openBox('currentuser');
box.put('currentavatar', avatar);
currentavatar = avatar;
notifyListeners();
}
Есть идеи Consumer
, как заставить поверить, что URL изменился, чтобы он обновился?
Ответ №1:
Я считаю Consumer
, что он будет перестроен, когда кто-нибудь позвонит notifyListeners()
. Ваша проблема может заключаться в Image.network(socialProvider.currentavatar,)
том, что flutter повторно использует один и тот же объект рендеринга, когда все не меняется. Вы можете попробовать добавить key:UniqueLey()
, чтобы принудительно перестраивать виджет при каждой его сборке.
Обновление с некоторым предположением. Вот простой код, который я пытаюсь перестроить в вашей среде:
class SimpleProvider with ChangeNotifier {
Future<void> reload() async => notifyListeners();
}
class TestConsumer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ChangeNotifierProvider(
create: (context) => SimpleProvider(),
child: Consumer<SimpleProvider>(
builder: (_, simpleProvider, child) {
print('Consumer build');
return child; // Here is your Image?
},
child: Builder(
builder: (context) {
print('Builder build');
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
context.read<SimpleProvider>().reload();
},
),
body: Container(),
);
},
),
),
),
);
}
}
Каждый раз, когда я нажимаю на кнопку, SimpleProvider
будет вызываться notifyListeners()
(будущее не обязательно), и builder
Consumer
будет вызываться функция in . Здесь возникают вопросы:
builder
Действительно ли вызывается, когда вы используете notifyListeners?
Я предполагаю, что вызывается функция builder . Вы все равно можете перепроверить эту часть. В противном случае вы должны указать, как вы его вызываете.
- Если
builder
вызывается, почему виджет изображения внутри него не перестраивается?
Это часть дизайна flutter, которую он использует столько, сколько может, для повышения производительности. Иногда людей смущает, что перестроение не происходит. Вот где, я думаю, ваша проблема здесь. Вы можете проверить базовый механизм из видео здесь: https://www.youtube.com/watch?v=996ZgFRENMsamp;ab_channel=Flutter
Комментарии:
1. Я пробовал это вместе с заменой потребителя на слушателя улья, но это все равно не работает. это то, что вы имели в виду? Image.network(‘${box.get(‘currentavatar’, defaultValue: ‘ example.com/default ,png’ )}’, ключ:uniqueKey(),;
2. Это также не работает с потребителем — Consumer<SocialProvider>( builder: (context, socialProvider, дочерний элемент) { return Image.network(snapshot.data[0], key:uniqueKey(), ); } ),
3. Я немного смущен вашим комментарием, который вы используете
socialProvider.currentavatar
в своем вопросе, но не в своем комментарии. Ваша проблема в том, что вы хотите перестроитьbuilder
функциюConsumer
правильно? Вы проверилиbuilder
, вызывается или нет послеnotifyListeners()
вызова?4. Извините за путаницу. Я экспериментировал с разными вещами, включая слушателя улья, социального провайдера и будущее. Я вернулся к исходному socialProvider.currentavatar.
5. Вот что-то интересное, что я нашел в статье на medium.com — «Следовательно, уникальные ключи должны использоваться только в виджетах без состояния, где виджеты не зависят от изменения внутренних данных». Так что я предполагаю, что именно поэтому key:uniqueKey() не сработал.