【问题标题】:How to call Provider on initState?如何在 initState 上调用 Provider?
【发布时间】:2021-05-22 23:30:46
【问题描述】:

如果isLiked 的值是truefalse,我有一个Provider,它会改变我的UI。该功能工作正常,但我注意到每次我重新启动应用程序时,UI 都会返回到其原始状态。如何保存其状态,以便在我终止应用时不会重新启动?

这是我的课:

class Selfie extends ChangeNotifier {


Selfie.fromDocument(DocumentSnapshot doc) {
   selfieId = doc['selfieId'] as String;
   ownerId = doc['ownerId'] as String;
   displayName = doc['displayName'] as String;
   photoUrl = doc['photoUrl'] as String;
   mediaUrl = doc['mediaUrl'] as String;
   timestamp = doc['timestamp'] as Timestamp;
   likes = doc['likes'] as Map;
   likesCount = doc['likesCount'] as int;
 }

String selfieId;
String ownerId;
String displayName;
String photoUrl;
String mediaUrl;
Timestamp timestamp;
Map likes;
int likesCount;


bool _isLiked = false;
bool get isLiked => _isLiked;
set isLiked(bool value) {
  _isLiked = value;
  notifyListeners();
}

bool _showHeart = false;
bool get showHeart => _showHeart;
set showHeart(bool value) {
  _showHeart = value;
  notifyListeners();
}

void handleLikePost(String userId, AuthUser authUser) {
   bool _isLiked = likes[userId] == true;
   if (_isLiked) {
    selfiesRef.doc(selfieId).update({
     'likes.$userId': false,
     'likesCount': FieldValue.increment(-1),
  });
  //removeLikeFromActivityFeed();

  //likeCount -= 1;
  isLiked = false;
  likes[userId] = false;


  selfiesRef.doc(selfieId).collection('likes').doc(userId).delete();
} else if (!_isLiked) {
  selfiesRef.doc(selfieId).update({
    'likes.$userId': true,
    'likesCount': FieldValue.increment(1),
  });
  selfiesRef.doc(selfieId).collection('likes').doc(userId).set({
    'displayName': authUser.displayName,
    'userId': userId,
    'photoUrl': authUser.photoUrl
  });
  //addLikeToActivityFed();

  //likeCount += 1;
  isLiked = true;
  likes[userId] = true;
  showHeart = true;



  Timer(Duration(milliseconds: 500), () {
    showHeart = false;
  });
}

notifyListeners();
 }
}

这是我的UI

class SelfieCard extends StatelessWidget {
final Selfie selfie;
final String userId;

SelfieCard({this.selfie, this.userId});
@override
Widget build(BuildContext context) {
  final AuthUser authUser =
    Provider.of<UserManager>(context, listen: false).authUser;
  return ChangeNotifierProvider.value(
    value: selfie,
    child: Consumer<Selfie>(
      builder: (_, selfie, __) {
        return Card(
          shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(15)),
          clipBehavior: Clip.antiAliasWithSaveLayer,
          elevation: 7,
          margin: EdgeInsets.symmetric(horizontal: 16, vertical: 4),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Consumer<UserManager>(
                builder: (_, userManager, __) {
                  bool isPostOwner = userManager.isLoggedIn
                      ? userManager.authUser.id == selfie.ownerId
                      : null;
                  return Padding(
                    padding: const EdgeInsets.only(top: 0.0, bottom: 0),
                    child: GestureDetector(
                      onTap: () {},
                      child: ListTile(
                          leading: CircleAvatar(
                            backgroundColor: Colors.grey,
                            backgroundImage: NetworkImage(selfie.photoUrl),
                          ),
                          title: Text(
                            selfie.displayName,
                            style: TextStyle(
                              fontFamily: 'BebasNeue',
                              fontSize: 19,
                              color: Colors.black,
                            ),
                          ),
                          trailing: userManager.isLoggedIn && isPostOwner
                              ? IconButton(
                                  onPressed: () {},
                                  icon: Icon(Icons.more_vert),
                                )
                              : Text('')),
                    ),
                  );
                },
              ),
              GestureDetector(
                onDoubleTap: () {},
                child: Stack(
                  alignment: Alignment.center,
                  children: <Widget>[
                    cachedNetworkImage(selfie.mediaUrl),
                    selfie.showHeart
                        ? Animator(
                            duration: Duration(milliseconds: 500),
                            tween: Tween(begin: 0.8, end: 1.4),
                            cycles: 0,
                            curve: Curves.bounceOut,
                            builder: (context, animatorState, chil) =>
                                Transform.scale(
                              scale: animatorState.value,
                              child: Icon(
                                Icons.favorite,
                                color: Colors.red,
                                size: 80,
                              ),
                            ),
                          )
                        : Text('')
                  ],
                ),
              ),
              Padding(
                padding: const EdgeInsets.only(top: 8.0, bottom: 10),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    Expanded(
                        child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Row(
                          children: [
                            Padding(
                              padding: const EdgeInsets.only(left: 20.0),
                              child: Text(
                                timeago.format(selfie.timestamp.toDate(),
                                    locale: 'en_short'),
                                style:
                                    TextStyle(fontWeight: FontWeight.bold),
                              ),
                            ),
                            Expanded(
                              child: Container(),
                            ),
                            GestureDetector(
                              onTap: () {
                                Navigator.push(
                                    context,
                                    MaterialPageRoute(
                                        builder: (context) => LikesScreen(
                                            postId: selfie.selfieId)));
                              },
                              child: Container(
                                margin: EdgeInsets.only(right: 10),
                                child: Text(
                                  selfie.likesCount.toString(),
                                  style: TextStyle(
                                      color: Colors.black,
                                      fontWeight: FontWeight.bold),
                                ),
                              ),
                            ),
                            Padding(
                              padding: EdgeInsets.only(
                                top: 40,
                              ),
                            ),
                            GestureDetector(
                              onTap: () {
                                selfie.handleLikePost(userId, authUser);
                              },
                              child: Icon(
                                selfie.isLiked
                                    ? Icons.favorite
                                    : Icons.favorite_border,
                                color: Colors.red,
                                size: 25,
                              ),
                            ),
                            Padding(
                              padding: EdgeInsets.only(top: 40, right: 10),
                            ),
                            SizedBox(
                              width: 20,
                            )
                          ],
                        ),
                      ],
                    )),
                  ],
                ),
              )
            ],
          ),
        );
      },
    ));
  }
 }

我知道我应该在initState 上拥有它,但我也知道initState 无法访问context。大家有什么办法解决吗?

【问题讨论】:

标签: flutter flutter-provider


【解决方案1】:

最终提供者 = Provider.of(context, listen:false);

【讨论】:

    【解决方案2】:

    问题是您的isLiked 变量最初总是为假。用户喜欢图像后,它会被存储,但您只是在本地临时存储它。

    为了保持一致,您可以将其永久存储在本地或 Firestore 中。如果要在本地存储,可以使用“Shared Preferences”、“SQfLite”、“Hive”等方式存储。但是,如果用户删除应用程序或清除数据,则效率不高,所有的数据可能会丢失。

    【讨论】:

    • 从 Firestore 获取价值对我有用。谢谢!
    【解决方案3】:

    您可以像在 build 方法中一样使用它...唯一的事情是您必须将 listen 设置为 false

    final provider = Provider.of<T>(context, listen: false);
    

    这里T 是您期望的状态类型

    查看this了解更多说明

    【讨论】:

    • 它没有用。我相信因为我的Provider 不在我的main 上。在这种情况下,我直接在我的Card 上使用ChangeNotifierProvider.value
    猜你喜欢
    • 2021-04-12
    • 2021-10-28
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 2021-02-15
    • 2019-08-29
    相关资源
    最近更新 更多