dart 离开页面后,用于收藏功能的图标按钮颜色未保持为指定的收藏颜色

yrdbyhpb  于 2023-07-31  发布在  其他
关注(0)|答案(1)|浏览(79)

我正在创建一个收藏功能,使用提供者收藏一个项目到收藏页面。下面是我的FavoriteProvider代码。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

import '../model/market_model.dart';

class FavoriteProvider extends ChangeNotifier {
  final List<CryptoItemModel> _favoriteItems = [];
  List<CryptoItemModel> get favoriteItems => _favoriteItems;

  FavoriteProvider() {
    fetchFavorites();
  }

  Future<void> toggleFavorite(CryptoItemModel item) async {
    final user = FirebaseAuth.instance.currentUser;
    if (user == null) {
      print('User is not logged in.');
      return;
    }

    final userEmail = user.email;
    final userRef =
        FirebaseFirestore.instance.collection('userData').doc(userEmail);

    try {
      final index =
          _favoriteItems.indexWhere((favItem) => favItem.name == item.name);
      if (index != -1) {
        _removeFavoriteByIndex(index);
        await userRef.collection('favorites').doc(item.name).delete();
      } else {
        _favoriteItems.add(item);
        await userRef.collection('favorites').doc(item.name).set(item.toMap());
      }
      notifyListeners();
    } catch (e) {
      print('Error toggling favorite: $e');
    }
  }

  Future<void> fetchFavorites() async {
    try {
      final user = FirebaseAuth.instance.currentUser;
      if (user == null) {
        print('User is not logged in.');
         return;
      }

      final userEmail = user.email;
      final userRef =
          FirebaseFirestore.instance.collection('userData').doc(userEmail);

      final snapshot = await userRef.collection('favorites').get();
      final favoriteList = snapshot.docs
          .map((doc) => CryptoItemModel.fromMap(doc.data()))
          .toList();

      _favoriteItems.clear();
      _favoriteItems.addAll(favoriteList);
    } catch (e) {
      print('Error retrieving favorites: $e');
    }

    notifyListeners();
  }

  bool isExist(CryptoItemModel item) {
    final isExist = _favoriteItems.contains(item);
    return isExist;
  }

  void _removeFavoriteByIndex(int index) {
    if (index >= 0 && index < _favoriteItems.length) {
      _favoriteItems.removeAt(index);
      notifyListeners();
    }
  }

  static FavoriteProvider of(BuildContext context, {bool listen = true}) {
    return Provider.of<FavoriteProvider>(context, listen: listen);
  }
}

字符串
这里是我在另一个文件中调用favorite函数的地方。

Consumer<FavoriteProvider>(
                                  builder: (context, provider, _) {
                                    return IconButton(
                                      iconSize: 35,
                                      onPressed: () {
                                        Provider.of<FavoriteProvider>(context,
                                                listen: false)
                                            .toggleFavorite(item);
                                      },
                                      icon: provider.isExist(item)
                                          ? const Icon(Icons.star,
                                              color: Colors.yellow)
                                          : const Icon(Icons.star_outline,
                                              color: Colors.grey),
                                    );
                                  },


这是将存储收藏项目的页面。

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/provider.dart';

import '../body/market_body.dart';
import '../cubit/bottom_navigation_cubit.dart.dart';
import '../provider/watchlist_provider.dart';
import '../widget/bottom_navigation.dart';
import '../widget/market_card.dart';

class WatchList extends StatefulWidget {
  const WatchList({Key? key}) : super(key: key);

  @override
  _WatchListState createState() => _WatchListState();
}

class _WatchListState extends State<WatchList> {
  @override
  void initState() {
    super.initState();
    final favoriteProvider =
        Provider.of<FavoriteProvider>(context, listen: false);
    favoriteProvider.fetchFavorites().then((_) {
      if (mounted) {
        setState(() {});
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return BlocProvider<BottomNavigationBarCubit>(
      create: (context) => BottomNavigationBarCubit(3),
      child: Scaffold(
        backgroundColor: Colors.white,
        appBar: AppBar(
          automaticallyImplyLeading: false,
          backgroundColor: const Color(0xFF0D0D2B),
          title: Image.asset(
            'assets/light_logo.png',
            width: 150.0,
          ),
          centerTitle: true,
        ),
        body: Padding(
          padding: const EdgeInsets.all(10.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Padding(
                padding: EdgeInsets.only(top: 18.0, left: 12.0),
                child: Column(
                  children: const [
                    Text(
                      'Watchlist',
                      textAlign: TextAlign.start,
                      style:
                          TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
                    ),
                  ],
                ),
              ),
              Padding(
                padding: EdgeInsets.only(top: 10.0, left: 12.0),
                child: Column(
                  children: const [
                    Text(
                      'View your favorite coins here!',
                      style: TextStyle(fontSize: 15, color: Color(0xFFBB0163)),
                    ),
                  ],
                ),
              ),
              const SizedBox(
                height: 10,
              ),
              Expanded(
                child: Consumer<FavoriteProvider>(
                  builder: (context, provider, _) {
                    final favoriteItems = provider.favoriteItems;

                    if (favoriteItems.isEmpty) {
                      return const Center(
                        child: Padding(
                          padding: EdgeInsets.all(18.0),
                          child: Text(
                            "Oops.. you have nothing on your watchlist",
                            style: TextStyle(fontSize: 16),
                          ),
                        ),
                      );
                    }

                    return ListView.builder(
                      itemCount: favoriteItems.length,
                      itemBuilder: (context, index) {
                        final item = favoriteItems[index];
                        return GestureDetector(
                          onTap: () {
                            Navigator.push(
                              context,
                              MaterialPageRoute(
                                builder: (context) => CryptoDescr(
                                  currency: item,
                                ),
                              ),
                            );
                          },
                          child: MarketCard(
                            name: item.name,
                            symbol: item.symbol,
                            price: item.price,
                            change: item.change,
                            percent: item.percent,
                            imageUrl: item.imageUrl,
                            marketCap: item.marketCap,
                          ),
                        );
                      },
                    );
                  },
                ),
              ),
            ],
          ),
        ),
        bottomNavigationBar: const BottomNavigation(),
      ),
    );
  }
}


我可以让项目存储在FireBase内好的,当你点击星星图标按钮收藏它时,颜色会像预期的那样变成黄色。但是当我离开页面并返回时,iconButton将更改回以前的位置,就好像该项目没有添加到收藏夹中,但它确实被添加了。
有没有一种方法,我可以解决这个问题,如果是这样,有人可以请帮助我。

ktca8awb

ktca8awb1#

我终于解决了这个问题!
我遇到的问题是因为isExist方法使用了contains方法,该方法只检查对象是否相等,而不比较项的属性。
所以我所做的是,我更新了FavoriteProvider类中的isExist方法,以比较项目的属性,而不是使用contains方法。
这里是它现在的样子:

bool isExist(CryptoItemModel item) {
  final isExist = _favoriteItems.any(
    (favItem) => favItem.name == item.name,
  );
  return isExist;
}

字符串
现在,每当我离开包含iconButton页面,然后再回来,iconButton将保持为收藏夹!

相关问题