Flutter股票信息查询插件stock的使用

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

Flutter股票信息查询插件stock的使用

插件简介

Stock 是一个用于从远程和本地来源加载数据的 Dart 包。它受到了 Store Kotlin 库的启发,主要目的是防止过度调用网络和磁盘缓存。通过使用 Stock,可以避免用相同的请求淹没网络,同时添加缓存层。

虽然可以在没有本地源的情况下使用 Stock,但结合本地数据库(如 Floor、Drift、Sqflite、Realm 等)可以获得最大的好处。

stock

Pub Codecov Dart CI style: very good analysis

主要特性

  • 组合本地和网络数据:提供一个数据 Stream 以监听和处理数据。
  • 了解数据流状态:对于显示错误或加载指示器非常有用。
  • 内存缓存:如果未使用本地数据库,Stock 提供内存缓存来共享和改善应用体验。
  • 更安全地处理数据:如果发生错误,Stock 会捕获并返回到流中,以便轻松处理。

概述

Stock 负责管理特定的数据请求,基于两个重要类:

  • Fetcher:定义如何通过网络获取数据。
  • SourceOfTruth:定义如何在本地缓存中读取和写入数据。

Stock 使用泛型键作为数据标识符。创建 Stock 后,可以通过 stream() 方法访问数据流,更新 UI 或执行特定操作。

快速上手

1. 创建 Fetcher

Fetcher 用于从网络获取新数据。可以从 FutureStream 创建。

final futureFetcher = Fetcher.ofFuture<String, List<Tweet>>(
  (userId) => _api.getUserTweets(userId),
);

final streamFetcher = Fetcher.ofStream<String, List<Tweet>>(
  (userId) => _api.getUserTweetsStream(userId),
);

2. 创建 SourceOfTruth

SourceOfTruth 用于在本地缓存中读取和写入远程数据。通常使用本地数据库实现,也可以使用内存缓存。

final sourceOfTruth = SourceOfTruth<String, List<Tweet>>(
  reader: (userId) => _database.getUserTweets(userId),
  writer: (userId, tweets) => _database.writeUserTweets(userId, tweets),
  delete: (userId) => _database.deleteUserTweets(userId), // 可选
  deleteAll: () => _database.deleteAllTweets(), // 可选
);

3. 创建 Stock

Stock 组合不同的数据源并获取数据。

final stock = Stock<String, List<Tweet>>(
  fetcher: fetcher,
  sourceOfTruth: sourceOfTruth,
);

获取数据流

通过 stream() 方法生成数据流,并使用 key 和可选的 refresh 参数。

stock
    .stream('user_id', refresh: true)
    .listen((StockResponse<List<Tweet>> stockResponse) {
  stockResponse.when(
    onLoading: (origin) => _displayLoadingIndicator(),
    onData: (origin, data) => _displayTweetsInUI(data),
    onError: (origin, error, stacktrace) => _displayErrorInUi(error),
  );
});

非流式数据获取

Stock 还提供了几种方法来获取非流式数据:

  • get:返回缓存数据(如果有),否则返回网络数据并更新缓存。
  • fresh:返回新鲜数据并更新缓存。
  • clear:清除特定条目。
  • clearAll:清除所有条目。
// 获取新鲜数据
final List<Tweet> freshTweets = await stock.fresh(key);

// 获取缓存数据
final List<Tweet> cachedTweets = await stock.get(key);

// 清除特定条目
await stock.clear(key);

// 清除所有条目
await stock.clearAll();

示例代码

以下是一个完整的示例代码,展示了如何使用 Stock 查询股票信息。

import 'package:stock/stock.dart';

late TwitterApi _api;
late TweetsLocalDatabase _database;

void main() async {
  // 创建 Fetcher
  final fetcher = Fetcher.ofFuture<String, List<Tweet>>(
    (userId) => _api.getUserTweets(userId),
  );

  // 创建 SourceOfTruth
  final sourceOfTruth = SourceOfTruth<String, List<Tweet>>(
    reader: (userId) => _database.getUserTweets(userId),
    writer: (userId, tweets) => _database.writeUserTweets(userId, tweets),
  );

  // 创建 Stock
  final stock = Stock<String, List<Tweet>>(
    fetcher: fetcher,
    sourceOfTruth: sourceOfTruth,
  );

  // 创建一个监听用户 `xmartlabs` 的推文变化的流
  stock
      .stream('xmartlabs', refresh: true)
      .listen((StockResponse<List<Tweet>> stockResponse) {
    stockResponse.when(
      onLoading: (_) => _displayLoadingIndicator(),
      onData: (_, data) => _displayTweetsInUI(data),
      onError: (_, error, __) => _displayErrorInUi(error),
    );
  });

  // 从网络获取 Xmartlabs 的推文并保存到数据库
  final List<Tweet> freshTweets = await stock.fresh('xmartlabs');

  // 获取 Xmartlabs 的推文
  // 尝试使用本地数据库中的推文,如果为空则从网络获取并保存到数据库
  final List<Tweet> cachedTweets = await stock.get('xmartlabs');
}

void _displayTweetsInUI(List<Tweet>? tweets) {}

void _displayLoadingIndicator() {}

void _displayErrorInUi(Object error) {}

// 示例实体
class Tweet {
  // 推文信息,如文本
}

// 示例 REST 服务
abstract class TwitterApi {
  // 获取特定用户的推文
  Future<List<Tweet>> getUserTweets(String userId);
}

// 示例本地数据库
abstract class TweetsLocalDatabase {
  // 从本地数据库获取用户的推文
  Stream<List<Tweet>> getUserTweets(String userId);

  // 替换数据库中的推文
  // 通常在数据库事务中进行,先删除旧推文再添加新推文
  Future<List<Tweet>> writeUserTweets(String userId, List<Tweet>? tweets);
}

通过以上步骤,你可以轻松地在 Flutter 应用中集成 Stock 插件,实现高效的数据管理和缓存功能。


更多关于Flutter股票信息查询插件stock的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter股票信息查询插件stock的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用Flutter中的stock插件来查询股票信息的示例代码。需要注意的是,stock插件的具体实现和功能可能因版本而异,且Flutter社区中的插件众多,这里假设我们使用的是一个较为通用的股票信息查询插件。如果具体插件名称有所不同,请参考对应插件的官方文档。

首先,确保在pubspec.yaml文件中添加了对stock插件的依赖(这里以假设的插件名为flutter_stock_info为例):

dependencies:
  flutter:
    sdk: flutter
  flutter_stock_info: ^x.y.z  # 替换为实际版本号

然后,运行flutter pub get来安装依赖。

接下来,在您的Flutter项目中,您可以按照以下方式使用插件来查询股票信息:

import 'package:flutter/material.dart';
import 'package:flutter_stock_info/flutter_stock_info.dart';  // 假设插件导入路径

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Stock Information App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: StockInfoScreen(),
    );
  }
}

class StockInfoScreen extends StatefulWidget {
  @override
  _StockInfoScreenState createState() => _StockInfoScreenState();
}

class _StockInfoScreenState extends State<StockInfoScreen> {
  String? stockSymbol = 'AAPL';  // 默认查询的股票代码
  StockInfo? stockInfo;
  bool isLoading = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Stock Information'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(
              decoration: InputDecoration(
                labelText: 'Stock Symbol',
              ),
              onChanged: (value) {
                setState(() {
                  stockSymbol = value;
                });
              },
            ),
            SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  isLoading = true;
                });
                
                // 使用插件查询股票信息
                FlutterStockInfo.getStockInfo(stockSymbol!)
                  .then((info) {
                    setState(() {
                      stockInfo = info;
                      isLoading = false;
                    });
                  })
                  .catchError((error) {
                    print('Error fetching stock info: $error');
                    setState(() {
                      stockInfo = null;
                      isLoading = false;
                    });
                  });
              },
              child: Text('Get Stock Info'),
            ),
            SizedBox(height: 16),
            if (isLoading)
              CircularProgressIndicator()
            else if (stockInfo != null)
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text('Company Name: ${stockInfo!.companyName}'),
                  Text('Price: \$${stockInfo!.price}'),
                  Text('Change: ${stockInfo!.change}%'),
                  // 根据插件提供的字段展示更多信息
                ],
              )
            else
              Text('No stock information available.'),
          ],
        ),
      ),
    );
  }
}

// 假设的FlutterStockInfo类和方法(实际插件可能不同)
class FlutterStockInfo {
  static Future<StockInfo> getStockInfo(String symbol) async {
    // 模拟网络请求,实际应使用HTTP请求或其他API
    await Future.delayed(Duration(seconds: 2));  // 模拟延迟
    return StockInfo(
      companyName: 'Apple Inc.',  // 示例数据
      price: 150.50,
      change: 1.23,  // 百分比变化
      // 其他字段...
    );
  }
}

// 假设的股票信息数据类
class StockInfo {
  final String companyName;
  final double price;
  final double change;
  // 其他字段...

  StockInfo({
    required this.companyName,
    required this.price,
    required this.change,
    // 其他初始化参数...
  });
}

请注意,上面的FlutterStockInfo类和StockInfo类是假设的,实际插件会有自己的API和数据结构。您应该参考所使用插件的官方文档来正确调用API和处理数据。

此外,由于股票信息通常是通过网络API获取的,因此在实际应用中,您可能需要处理网络错误、超时等问题,并可能需要添加适当的错误处理和用户反馈机制。

回到顶部