Flutter 如何在终止任务后使用 Hive 管理 ListView 的状态?

问题描述 投票:0回答:1

我正在尝试开发一个书签应用程序,您可以添加和删除项目。我正在使用 Hive 来管理 ListView 上项目的状态,但它没有按我的预期工作。我的期望是在杀死任务后添加到 ListView 上的项目仍然在视图中。另外,另一个期望是,如果我删除默认项目(Google 和 Apple)并终止任务,这些项目将被删除。我如何使用 Hive 来实现这些?

late Box box;
const bookmarkBox = 'bookmark_box';

Future<void> main() async {

  await Hive.initFlutter();

  box = await Hive.openBox(bookmarkBox);
  runApp(const BookmarkApp());
}

class BookmarkApp extends StatelessWidget {
  const BookmarkApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Bookmark App',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.white),
        useMaterial3: false,
      ),
      home:  BookmarkListPage(text: '', url: '',),
    );
  }
}

class BookmarkListPage extends StatefulWidget {
  BookmarkListPage({super.key, title, required this.text, required this.url});

  String text;
  String url;

  final String title = 'Bookmark';

  @override
  State<BookmarkListPage> createState() => _BookmarkListPageState();
}

class _BookmarkListPageState extends State<BookmarkListPage> {

// these are default value but you are able to delete them
  List<String> bookmarkList = ['Google', 'Apple'];
  List<String> bookmarkUrl = [
    'https://www.google.com/',
    'https://www.apple.com/jp/',
  ];

  _launchUrl(int index) async {
    var url = Uri.parse(bookmarkUrl[index]);
    if (await canLaunchUrl(url)) {
      await launchUrl(url);
    } else {
      throw "Could not open $url";
    }
  }

  @override
  Widget build(BuildContext context) {

    var box = Hive.box(bookmarkBox);

    box.get('BookmarkTitle', defaultValue: 'Not Title');
    box.get('BookmarkUrl', defaultValue: 'No URL');

    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        backgroundColor: Colors.white,
        title: Text(
          widget.title,
          style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
        ),
        bottom: PreferredSize(
          child: Container(
            height: 1,
            color: Colors.black,
          ),
          preferredSize: Size.fromHeight(1),
        ),
      ),
      body: ListView.builder(
        itemCount: bookmarkList.length,
        itemBuilder: (context, index) {
          // you can swipe to delete items
          return Dismissible(
            background: Container(
              color: Colors.red,
              child: Icon(
                Icons.delete,
                color: Colors.white,
              ),
            ),
            onDismissed: (direction) {
              setState(() {
                bookmarkList.removeAt(index);
              });
            },
            key: UniqueKey(),
            child: Card(
              child: ListTile(
                title: Text(
                  bookmarkList[index],
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: 20,
                  ),
                ),
                subtitle: Text(bookmarkUrl[index]),
                onTap:() => _launchUrl(index),
              ),
            ),
          );
        },
      ),

     
      floatingActionButton: FloatingActionButton(
        shape: const CircleBorder(),
        backgroundColor: Colors.blue,
        onPressed: () async {
          final (newBookmarkTitle, newBookmarkUrl) = await showDialog(
              context: context,
              builder: (_) {
                return BookmarkDialog();
              });

          setState(() {
            bookmarkList.add(newBookmarkTitle);
            bookmarkUrl.add(newBookmarkUrl);
            box.put('BookmarkTitle', bookmarkList);
            box.put('BookmarkUrl', bookmarkUrl);
          });

        },
        child: const Icon(
          Icons.add,
          color: Colors.white,
        ),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

flutter hive flutter-listview
1个回答
0
投票

据我所知,你没有正确使用盒子

bookmarkList
bookmarkUrl
应始终与盒子中的内容相同。意味着这些列表中发生的每件事都应该反映在盒子上

所以:

  1. 实例化它们时:

    List<dynamic> bookmarkList = box.get('BookmarkTitle', defaultValue: ['Google', 'Apple']);
    List<dynamic> bookmarkUrl = box.get('BookmarkUrl', defaultValue: ['https://www.google.com/', 'https://www.apple.com/jp/']);
    
  2. 删除项目时:

        onDismissed: (direction) {
           setState(() {
             bookmarkList.removeAt(index);
             bookmarkUrl.removeAt(index);
             box.put('BookmarkTitle', bookmarkList);
             box.put('BookmarkUrl', bookmarkUrl);
           });
         },
    
  3. 添加新项目时,您做得正确:

       setState(() {
         bookmarkList.add(newBookmarkTitle);
         bookmarkUrl.add(newBookmarkUrl);
         box.put('BookmarkTitle', bookmarkList);
         box.put('BookmarkUrl', bookmarkUrl);
       });
    
© www.soinside.com 2019 - 2024. All rights reserved.