You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter开发:如何在ListView中添加多张默认书签卡片?

解决Flutter书签应用默认展示3个书签的问题

你的代码核心问题在于初始书签列表为空、删除操作未同步URL列表,且未结合Hive实现数据持久化。以下是针对性修复方案:

1. 初始化默认书签并从Hive加载数据

在initState中添加数据加载逻辑:首次打开时若Hive无数据,插入默认书签并保存;已有数据则直接加载。

@override
void initState() {
  super.initState();
  _loadBookmarks();
}

void _loadBookmarks() async {
  var box = Hive.box(bookmarkBox);
  // 从Hive读取已存储的书签数据
  List<String>? savedTitles = box.get('bookmarkTitles')?.cast<String>();
  List<String>? savedUrls = box.get('bookmarkUrls')?.cast<String>();

  if (savedTitles == null || savedUrls == null || savedTitles.isEmpty) {
    // 设置默认书签
    bookmarkList = ['Google', 'Apple', 'Facebook'];
    bookmarkUrl = ['https://www.google.com', 'https://www.apple.com', 'https://www.facebook.com'];
    // 保存到Hive实现持久化
    await box.put('bookmarkTitles', bookmarkList);
    await box.put('bookmarkUrls', bookmarkUrl);
  } else {
    // 加载已存在的书签
    bookmarkList = savedTitles;
    bookmarkUrl = savedUrls;
  }
  setState(() {});
}

2. 同步删除书签的标题与URL

删除操作需同时移除两个列表的对应元素,并更新Hive数据,避免索引不匹配或数据丢失:

onDismissed: (direction) {
  setState(() {
    bookmarkList.removeAt(index);
    bookmarkUrl.removeAt(index); // 同步删除URL列表的对应项
  });
  // 更新Hive中的存储数据
  var box = Hive.box(bookmarkBox);
  box.put('bookmarkTitles', bookmarkList);
  box.put('bookmarkUrls', bookmarkUrl);
},

3. 优化Dismissible的Key

用ValueKey替代UniqueKey,确保每个书签项的标识稳定,避免不必要的UI重绘和动画异常:

key: ValueKey(bookmarkList[index]), // 用书签名作为唯一标识

完整修改后的代码

class _BookmarkListPageState extends State<BookmarkListPage> {
  List<String> bookmarkList = [];
  List<String> bookmarkUrl = [];

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

  @override
  void initState() {
    super.initState();
    _loadBookmarks();
  }

  void _loadBookmarks() async {
    var box = Hive.box(bookmarkBox);
    List<String>? savedTitles = box.get('bookmarkTitles')?.cast<String>();
    List<String>? savedUrls = box.get('bookmarkUrls')?.cast<String>();

    if (savedTitles == null || savedUrls == null || savedTitles.isEmpty) {
      bookmarkList = ['Google', 'Apple', 'Facebook'];
      bookmarkUrl = ['https://www.google.com', 'https://www.apple.com', 'https://www.facebook.com'];
      await box.put('bookmarkTitles', bookmarkList);
      await box.put('bookmarkUrls', bookmarkUrl);
    } else {
      bookmarkList = savedTitles;
      bookmarkUrl = savedUrls;
    }
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    var box = Hive.box(bookmarkBox);

    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) {
          return Dismissible(
            background: Container(
              color: Colors.red,
              child: Icon(
                Icons.delete,
                color: Colors.white,
              ),
            ),
            onDismissed: (direction) {
              setState(() {
                bookmarkList.removeAt(index);
                bookmarkUrl.removeAt(index);
              });
              box.put('bookmarkTitles', bookmarkList);
              box.put('bookmarkUrls', bookmarkUrl);
            },
            key: ValueKey(bookmarkList[index]),
            child: Card(
              child: ListTile(
                title: Text(
                  bookmarkList[index],
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: 20,
                  ),
                ),
                subtitle: Text(bookmarkUrl[index]),
                onTap: () => _launchUrl(index),
              ),
            ),
          );
        },
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 19:20:32