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

Flutter搜索后无法即时显示书籍按钮,需手动刷新问题求助

问题分析与解决方案

核心问题

你的代码有两个关键问题导致按钮无法即时显示:

  1. 页面跳转与数据加载顺序错误:点击搜索按钮后先跳转到AfterSearchScreen,再异步加载书籍数据,此时页面已经渲染完成,不会感知后续的数据变化。
  2. 全局变量更新无状态通知:即使数据加载完成并添加到infoTitle,AfterSearchScreen的状态不会自动刷新,只有热重载时才会重新构建页面读取新数据。

修复方案(推荐:数据传递替代全局变量)

直接调整逻辑,先加载完书籍数据,再将数据传递给目标页面,同时移除全局变量避免状态混乱:

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

class FinderBookSearch extends StatefulWidget {
  const FinderBookSearch({super.key, required this.title});
  final String title;

  @override
  State<FinderBookSearch> createState() => _FinderBookSearch();
}

class _FinderBookSearch extends State<FinderBookSearch> {
  final TextEditingController _searchController = TextEditingController();
  String inputText = '';

  // 先加载数据,再跳转页面
  Future<void> searchAndNavigate() async {
    if (inputText.isEmpty) return;
    
    final books = await queryBooks(
      inputText,
      maxResults: 20,
      printType: PrintType.books,
      orderBy: OrderBy.relevance,
      reschemeImageLinks: true,
      langRestrict: "en",
    );
    
    // 提取书籍标题列表
    final List<String> bookTitles = books.map((book) => book.info.title).toList();
    
    // 跳转并传递数据
    if (mounted) {
      Navigator.push(
        context,
        MaterialPageRoute(
          builder: (_) => AfterSearchScreen(bookTitles: bookTitles),
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          backgroundColor: Colors.white,
          title: Container(
            padding: const EdgeInsets.symmetric(horizontal: 8.0),
            child: TextField(
              onChanged: (text) {
                setState(() {
                  inputText = text;
                });
              },
              controller: _searchController,
              decoration: InputDecoration(
                hintText: 'Search...',
                suffixIcon: IconButton(
                  icon: const Icon(Icons.clear, color: Colors.black),
                  onPressed: () => _searchController.clear(),
                ),
                prefixIcon: IconButton(
                  icon: const Icon(Icons.search, color: Colors.black),
                  onPressed: searchAndNavigate, // 调用修改后的方法
                ),
              ),
            ),
          )),
    );
  }
}

class AfterSearchScreen extends StatelessWidget {
  final List<String> bookTitles;

  const AfterSearchScreen({super.key, required this.bookTitles});

  Widget _buildBookButton(String text) {
    return ElevatedButton(
      style: const ButtonStyle(),
      onPressed: () {},
      child: ListTile(
        title: Text(text, style: const TextStyle(color: Colors.black)),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Container(
        decoration: const BoxDecoration(color: Colors.greenAccent),
        child: ListView.builder(
          itemCount: bookTitles.length,
          itemBuilder: (context, index) {
            return _buildBookButton(bookTitles[index]);
          },
        ),
      ),
    );
  }
}

修复说明

  1. 调整执行顺序:searchAndNavigate方法先异步加载书籍数据,完成后再跳转到AfterSearchScreen,确保页面打开时已有数据。
  2. 移除全局变量:通过构造函数将书籍标题列表直接传递给AfterSearchScreen,避免全局状态导致的不可控问题。
  3. 简化组件:AfterSearchScreen改为无状态组件,因为数据由父页面传递,无需内部状态管理。

设备兼容性说明

代码本身不包含平台特定逻辑,只要books_finder包支持对应的平台(iOS、Android是主流支持平台),就能正常运行。需要注意:

  • Android:在android/app/src/main/AndroidManifest.xml中添加网络权限:
    <uses-permission android:name="android.permission.INTERNET" />
    
  • iOS:确保项目已启用网络访问(默认新建项目已支持HTTPS请求,若需HTTP需修改Info.plist配置)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 14:28:23