Flutter数据缓存查询插件cached_query_flutter的使用

发布于 1周前 作者 wuwangju 来自 Flutter

Flutter数据缓存查询插件cached_query_flutter的使用

cached_query_flutter 是一个为Flutter应用程序提供强大的数据缓存和查询功能的插件。它简化了与服务器交互的数据管理,支持离线优先的工作流,并且提供了几个方便的小部件来构建响应式的用户界面。下面我们将详细介绍如何安装、配置以及使用这个插件。

功能特性

  • 网络连接恢复时重新获取查询:当设备重新建立网络连接时自动刷新缓存。
  • 应用返回前台时重新获取查询:在应用从后台切换到前台时自动更新数据。
  • 内置的Builder组件:用于处理普通查询(QueryBuilder)、无限滚动查询(InfiniteQueryBuilder)及变更操作(MutationBuilder)。

快速开始

安装依赖

首先,在pubspec.yaml文件中添加对cached_query_flutter的依赖:

dependencies:
  cached_query_flutter: ^最新版本号

然后运行flutter pub get来下载并安装该库。

初始化配置

为了使cached_query_flutter正常工作,需要对其进行初始化设置。这通常是在应用程序启动时完成的。可以使用configFlutter方法来进行全局配置:

import 'package:cached_query_flutter/cached_query_flutter.dart';
import 'package:cached_storage/cached_storage.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Initialize CachedQuery with global configurations.
  await CachedQuery.instance.configFlutter(
    config: QueryConfigFlutter(
      refetchOnConnection: true,  // Re-fetch on network connection changes.
      refetchOnResume: true,      // Re-fetch when app comes back to foreground.
    ),
    storage: await CachedStorage.ensureInitialized(), // Persistent storage setup.
  );

  runApp(MyApp());
}

这里我们指定了两个重要的选项:

  • refetchOnConnection: 当检测到网络状态变化时是否重新加载数据。
  • refetchOnResume: 应用程序从后台切换到前台时是否重新加载数据。

同时,我们也初始化了一个持久化存储实例,确保即使应用程序关闭后数据仍然能够保存下来。

使用方式

cached_query_flutter 提供了几种不同的builder小部件,它们可以帮助你更轻松地创建基于查询结果的UI组件。接下来我们将逐一介绍这些组件,并给出具体的例子。

QueryBuilder

QueryBuilder 是最基础也是最常用的builder类型,它可以用来显示单个查询的结果。每当查询的状态发生变化时,QueryBuilder 都会触发重建。

class FilmTitle extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Film Title')),
      body: QueryBuilder<String>(
        query: getFilmTitle(),
        builder: (context, state) {
          if (state.status == QueryStatus.loading) {
            return Center(child: CircularProgressIndicator());
          }
          return Center(child: Text(state.data ?? ""));
        },
      ),
    );
  }

  Query<String> getFilmTitle() {
    return Query<String>(
      key: 'title',
      config: const QueryConfig(cacheDuration: Duration(seconds: 4)),
      queryFn: () => Future.delayed(Duration(milliseconds: 400), () => "Star Wars"),
    );
  }
}

在这个例子中,getFilmTitle() 函数定义了一个简单的查询逻辑,它模拟了一次API调用,返回电影标题字符串。而QueryBuilder 则负责根据查询的不同状态(如加载中、成功或失败)来渲染相应的UI元素。

InfiniteQueryBuilder

对于需要分页加载大量数据的情况,可以使用InfiniteQueryBuilder 来实现无限滚动效果。它允许你在页面底部加载更多内容,非常适合列表视图等场景。

InfiniteQueryBuilder<List<PostModel>, int>(
  query: query,
  builder: (context, state, infiniteQuery) {
    return ListView.builder(
      itemCount: state.data?.length ?? 0 + 1,
      itemBuilder: (context, index) {
        if (index >= state.data!.length) {
          return Center(child: CircularProgressIndicator());
        }
        final post = state.data![index];
        return ListTile(title: Text(post.title));
      },
      controller: ScrollController()..addListener(() {
        if (_controller.position.extentAfter < 500) {
          infiniteQuery.getNextPage();
        }
      }),
    );
  },
)

请注意,这里的代码片段只是一个简化的示例,实际项目中可能还需要考虑错误处理、空数据展示等情况。

MutationBuilder

当你想要执行某些变更操作(例如提交表单或发送请求)时,可以使用MutationBuilder 。它会在变更操作完成后通知UI进行相应的变化。

MutationBuilder<PostModel, PostModel>(
  mutation: _postService.createPost(),
  builder: (context, state, mutate) {
    return ElevatedButton(
      onPressed: () async {
        try {
          await mutate(PostModel(title: "New Post"));
          ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Post created")));
        } catch (e) {
          ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Failed to create post")));
        }
      },
      child: Text("Create Post"),
    );
  },
);

通过这种方式,你可以很容易地将变更逻辑集成到你的Flutter应用中,并且利用cached_query_flutter 的优势来管理和优化数据流程。

结合BLoC模式

cached_query_flutter 与BLoC(Business Logic Component)模式结合得非常好,可以让你的应用程序结构更加清晰、易于维护。以下是两种常见的集成方式:

直接在UI层使用查询

一种简单的方法是直接在UI层持有Query 对象作为BLoC状态的一部分。这样做的好处是可以继续使用所有的查询builders,并且cached_query_flutter 可以准确地知道哪些查询正在被使用。

从领域层流式传输

另一种方法是从领域层创建查询,并让BLoC监听查询流的变化。这种方法更容易集成到现有项目中,因为你只需要对领域层和BLoC层做少量修改即可。

// Domain layer - Repository
Query<JokeModel?> getJoke() {
  return Query<JokeModel?>(
    key: 'joke',
    queryFn: () async => JokeModel.fromJson(await _service.getJoke()),
  );
}

// BLoC layer
FutureOr<void> _onJokeFetched(JokeFetched event, Emitter<JokeState> emit) {
  return emit.forEach<QueryState<JokeModel?>>(
    _repo.getJoke().stream,
    onData: (query) => state.copyWith(
      joke: query.data,
      status: query.status == QueryStatus.loading ? JokeStatus.loading : JokeStatus.success,
    ),
  );
}

以上就是关于cached_query_flutter 插件的基本介绍及其在Flutter开发中的应用。希望这篇文章能帮助你更好地理解和使用这个强大的工具!如果你有任何问题或者需要进一步的帮助,请随时提问。


更多关于Flutter数据缓存查询插件cached_query_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据缓存查询插件cached_query_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,cached_query_flutter 是一个用于在 Flutter 应用中实现数据缓存和查询的插件。虽然无法直接提供完整的插件实现代码(因为那是插件作者的工作),但我可以向你展示如何使用该插件来缓存和查询数据的一个基本示例。

首先,你需要确保你的 Flutter 项目中已经添加了 cached_query_flutter 插件。你可以在你的 pubspec.yaml 文件中添加以下依赖项:

dependencies:
  flutter:
    sdk: flutter
  cached_query_flutter: ^最新版本号  # 替换为实际的最新版本号

然后运行 flutter pub get 来获取依赖项。

接下来,我将展示一个如何使用 cached_query_flutter 插件的示例代码。

示例代码

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Cached Query Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // 创建一个 CachedQuery 实例
  final CachedQuery<String, String> cachedQuery = CachedQuery<String, String>(
    // 设置缓存有效期(例如:5秒)
    duration: Duration(seconds: 5),
    // 提供一个获取数据的函数(模拟从网络获取数据)
    fetchData: (key) async {
      // 这里可以替换为实际的网络请求
      await Future.delayed(Duration(seconds: 2)); // 模拟网络延迟
      return "Data for key: $key";
    },
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Cached Query Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Query Data:',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            // 使用 FutureBuilder 来异步获取数据
            FutureBuilder<String?>(
              future: cachedQuery.get('exampleKey'),
              builder: (context, snapshot) {
                if (snapshot.connectionState == ConnectionState.done) {
                  if (snapshot.hasError) {
                    return Text('Error: ${snapshot.error}');
                  } else if (snapshot.data == null) {
                    return Text('Loading...');
                  } else {
                    return Text(
                      'Cached or Fetched Data: ${snapshot.data!}',
                      style: TextStyle(fontSize: 18),
                    );
                  }
                } else {
                  return Text('Loading...');
                }
              },
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                // 清除缓存
                cachedQuery.clear('exampleKey');
              },
              child: Text('Clear Cache'),
            ),
          ],
        ),
      ),
    );
  }
}

解释

  1. CachedQuery 实例

    • duration:设置缓存的有效期。在这个例子中,缓存将在 5 秒后失效。
    • fetchData:一个异步函数,用于获取数据。在这个例子中,它模拟了一个网络请求,通过 Future.delayed 来模拟延迟。
  2. FutureBuilder

    • 用于异步获取数据并构建 UI。当 cachedQuery.get('exampleKey') 被调用时,它会首先检查缓存。如果缓存有效,它将立即返回缓存的数据;否则,它将调用 fetchData 函数来获取数据并将其缓存。
  3. Clear Cache 按钮

    • 调用 cachedQuery.clear('exampleKey') 来清除特定键的缓存。

这个示例展示了如何使用 cached_query_flutter 插件来实现数据的缓存和查询功能。你可以根据实际需求对代码进行修改和扩展。

回到顶部