我在我的一堂课中使用了全局变量。该全局变量的值在开始时为 null,但一段时间后它会从后台运行的函数中获取值。我希望当该全局变量的值发生更改时,它的值也应该更新到 UI。我正在为此使用提供商。但提供程序不会在 UI 上自动更新该变量的值,我必须重新访问屏幕才能显示更新后的值。检查我的代码,让我知道我的代码出了什么问题,以及为什么它没有在 UI 上实时更新变量的值。
import 'package:flutter/cupertino.dart';
class ProfilePicProvider extends ChangeNotifier {
String _profilepic = ''; // Initialize it with an empty string.
String get profilepic => _profilepic;
void updateProfilePic(String newProfilePic) {
_profilepic = newProfilePic;
notifyListeners();
}
}
以上是我的提供商模型。
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) {
return themeChangeProvider;
}),
ChangeNotifierProvider<ProfilePicProvider>.value(
value: ProfilePicProvider(),
),
],
child:
Consumer<DarkThemeProvider>(builder: (context, themeData, child) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
title: 'Shoot Your Shot',
theme: Styles.themeData(themeChangeProvider.darkTheme, context),
home: bottomNavigation(currentIndex: 0),
);
}));
}
这就是我在 main.dart 文件中调用它的方式。
import 'dart:io';
import 'package:datingapp/Screens/Dialogs/DeleteAccountDialog.dart';
import 'package:datingapp/Screens/EditProfile/EditProfile.dart';
import 'package:datingapp/Screens/MainScreens/UpdateEmail.dart';
import 'package:datingapp/Widgets/GradientSwitch.dart';
import 'package:datingapp/Widgets/GradientText.dart';
import 'package:datingapp/Widgets/loading.dart';
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../Onboarding/Upgrade.dart';
import '../../ThemeChange/_providerModel.dart';
import '../../global_variables.dart';
import '../../provider/ProfilePicProvider.dart';
import 'BlockedUsers.dart';
import 'FilterScreen.dart';
import 'Notifications.dart';
class Profile extends StatefulWidget {
const Profile({super.key});
@override
State<Profile> createState() => _ProfileState();
}
class _ProfileState extends State<Profile> {
String? userFirstname = name?.split(' ')[0];
String? age = "$userAge";
bool isLoading = true;
@override
void initState() {
super.initState();
print("user Images are: $userImagesList");
print("user profile pic is: $profilepic");
Future.delayed(const Duration(seconds: 2), () {
setState(() {
isLoading = false;
});
});
}
@override
Widget build(BuildContext context) {
Provider.of<ProfilePicProvider>(context, listen: false).updateProfilePic(profilepic);
final themeChange = Provider.of<DarkThemeProvider>(context);
return Scaffold(
body: SafeArea(
child: Stack(
children: [
SingleChildScrollView(
child: Column(
children: [
Container(
width: MediaQuery.of(context).size.width,
height: 850,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/profilebg2.png"),
fit: BoxFit.fill)),
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
onTap: () => openFiltersBottomSheet(context),
child: Image.asset(
"assets/images/gradient-filter-icon.png",
width: 33,
height: 33)),
GradientText(TextWidget: const Text(
'Profile',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.w900,
color: Colors.white,
),
)),
const SizedBox(width: 33)
],
),
const SizedBox(height: 30),
Consumer<ProfilePicProvider>(
builder: (context, profilePicProvider, child) {
return Stack(
children: [
Container(
width: 150,
height: 150,
decoration: const BoxDecoration(
shape: BoxShape.circle),
child: profilepic != null ? ClipRRect(borderRadius: BorderRadius.circular(200), child: Image.file(File(profilepic!), fit: BoxFit.cover)) : null,
),
Positioned(
right: 3,
bottom: 3,
child: GestureDetector(
onTap: () => Get.to(EditProfile()),
child: Container(
width: 34,
height: 34,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.white, width: 2),
color: Color(0xffC7C7CC)),
child: Center(
child: Icon(
Icons.edit,
color: Colors.white,
size: 20,
)),
),
),
),
],
);
},
),
const SizedBox(height: 10),
RichText(
text: TextSpan(
text: '$userFirstname ',
style: TextStyle(
fontFamily: "Avenir",
fontWeight: FontWeight.w800,
color:
Theme.of(context).textTheme.labelMedium?.color,
fontSize: 18,
),
children: [
TextSpan(
text: age,
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 15,
),
),
],
),
),
const SizedBox(height: 20),
Container(
width: MediaQuery.of(context).size.width,
height: 165,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20)),
gradient: const LinearGradient(
colors: [Color(0xff6814CE), Color(0xff296FF9)],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
),
child: Column(
children: [
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Shoot Your Shot ",
style: TextStyle(
fontStyle: FontStyle.italic,
fontWeight: FontWeight.w900,
color: Colors.white,
fontSize: 20)),
Padding(
padding: const EdgeInsets.only(top: 2),
child: Container(
width: 75,
height: 33,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
"assets/images/whitebg-text.png"),
fit: BoxFit.fill)),
child: Padding(
padding:
const EdgeInsets.only(bottom: 5),
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
GradientText(TextWidget: Text(
'M.V.P ',
style: TextStyle(
fontStyle: FontStyle.italic,
fontSize: 14,
fontWeight: FontWeight.w900,
color: Colors.white,
),
)),
Image.asset(
"assets/images/trophy-emoji.png",
width: 11,
height: 13,
)
],
),
)),
)
],
),
SizedBox(height: 15),
RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: 'First 3 days free!',
style: TextStyle(
fontFamily: "Avenir",
fontWeight: FontWeight.w900,
color: Color(0xffffffff),
fontSize: 16.5,
),
children: [
TextSpan(
text: '\nthen just \$19.97 / month',
style: TextStyle(
height: 1.2,
fontWeight: FontWeight.w500,
fontSize: 12.5,
),
),
],
),
),
SizedBox(height: 20),
GestureDetector(
onTap: () => Get.to(Upgrade()),
child: Container(
width: MediaQuery.of(context).size.width * 0.7,
height: 35,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.white),
child: Center(
child: GradientText(TextWidget: Text(
'Free Trial Upgrade',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w700,
color: Colors.white,
),
))
),
),
),
],
),
),
Container(
width: MediaQuery.of(context).size.width,
height: 350,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(20)),
color: Color(0x39D9D9D9)),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
const SizedBox(height: 20),
CustomFeaturesWidget(
label: "Shots",
description:
"Never run out of likes again with unlimited shots",
gradientText: "Unlimited",
iconPath:
"assets/images/shots-icon-rounded.png"),
const SizedBox(height: 20),
CustomFeaturesWidget(
label: "Chat Substitions",
description:
"The first three chats are on us! Thereafter, remove and replace unlimited chats at will",
gradientText: "Unlimited",
iconPath:
"assets/images/close-icon-rounded.png"),
const SizedBox(height: 20),
CustomFeaturesWidget(
label: "See Who Likes You",
description:
"Find out who is shooting their shot at you",
gradientText: "Unlimited",
iconPath:
"assets/images/eyes-icon-rounded.png"),
const SizedBox(height: 20),
CustomFeaturesWidget(
label: "Go backs",
description:
"Change of heart? Go back for another chance to like a users profile",
gradientText: "Unlimited",
iconPath: "assets/images/goback-icon.png"),
const SizedBox(height: 20),
CustomFeaturesWidget(
label: "Ads",
description:
"Focus on shooting your shot to find your match & never see an ad again!",
gradientText: "NO ADS",
iconPath: "assets/images/cross-icon.png"),
],
),
),
)
],
),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
CustomMenuWidget(
title: "Edit Email",
onClick: () => Get.to(UpdateEmail())),
const SizedBox(height: 30),
CustomMenuWidget(
title: "Blocked Users",
onClick: () => Get.to(BlockedUsers())),
const SizedBox(height: 30),
CustomMenuWidget(title: "Rate Us", onClick: () {}),
const SizedBox(height: 30),
CustomMenuWidget(title: "Invite a friend", onClick: () {}),
const SizedBox(height: 30),
CustomMenuWidget(
title: "Notifications",
onClick: () => Get.to(Notifications())),
const SizedBox(height: 30),
CustomMenuWidget(
title: "Send Support Email", onClick: () {}),
const SizedBox(height: 30),
CustomMenuWidget(title: "Safety Center", onClick: () {}),
const SizedBox(height: 30),
CustomMenuWidget(title: "Terms of Service", onClick: () {}),
const SizedBox(height: 30),
CustomMenuWidget(title: "Privacy Policy", onClick: () {}),
SizedBox(height: 30),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Dark Mode",
style: TextStyle(
fontWeight: FontWeight.w600,
color: Theme.of(context)
.textTheme
.labelMedium
?.color,
fontSize: 15)),
CustomSwitch(
activeColor: Colors.transparent,
value: themeChange.darkTheme,
onChanged: (bool value) {
themeChange.darkTheme = value;
},
),
]),
SizedBox(height: 50),
GradientText(TextWidget: Text(
'Log out',
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w700,
color: Colors.white,
),
)),
SizedBox(height: 30),
Text("Restore my purchases",
style: TextStyle(
fontWeight: FontWeight.w700,
color: Theme.of(context)
.inputDecorationTheme
.hintStyle
?.color,
fontSize: 14)),
SizedBox(height: 30),
GestureDetector(
onTap: () => DeleteAccountDialog.showResponseDialog(),
child: Text("Delete my account",
style: TextStyle(
fontWeight: FontWeight.w700,
color: Color(0xffF18A80),
fontSize: 14)),
),
SizedBox(height: 20),
Text("v1.0.0",
style: TextStyle(
fontWeight: FontWeight.w500,
color: Theme.of(context)
.inputDecorationTheme
.hintStyle
?.color,
fontSize: 11)),
SizedBox(height: 30)
],
),
)
],
),
),
Visibility(
visible: isLoading,
child: Loading(topPadding: 0))
],
),
),
);
}
}
在我使用全局变量 profilepic 和提供程序的值的类的代码上方。
String? imageUrl;
String profilepic = '';
List<String> userImagesList =[];
String? emailAddress;
String? name;
String? userBio;
String? userGender;
List<String> userGreenFlags = [];
List<String> userRedFlags = [];
int? userAge;
DateTime? userDOB;
这就是我的全局变量profilepic存储的地方。
我是提供商新手,对此了解不够。让我知道我需要做出哪些改变来解决这个问题
在 build() 方法中,您使用提供程序更新个人资料图片 消费者正在使用 profilePic 这是一个全局变量,您应该使用提供商的 profilePic。示例:
Consumer<ProviderClassName>(
builder: (context, provider, child) {
return NetworkImage(provider.profilePic);
},
),
这里的消费者正在观看provider.profilePic,每当它更新时,它就会重建NetworkImage小部件。