Flutter Apollo GraphQL 客户端插件apollo_flutter的使用

Flutter Apollo GraphQL 客户端插件 apollo_flutter 的使用

apollo_flutter 是一个用于在 Flutter 应用中集成 Apollo GraphQL 的客户端库。以下是如何在 Flutter 应用中使用 apollo_flutter 的详细步骤和示例代码。

安装

首先,在你的 pubspec.yaml 文件中添加 apollo_flutter 作为依赖项:

dependencies:
  apollo_flutter: ^<version>

然后运行 flutter pub get 来安装该包。

Android 配置

在项目的 local.properties 文件中添加 TekoGoogleRegistryToken(联系 trung.cs@teko.vn 获取):

// android/local.properties

TekoGoogleRegistry.password=<your-token>

在项目 build.gradle 文件中添加以下代码:

allprojects {
    repositories {
        ...

        Properties properties = new Properties()
        properties.load(project.rootProject.file('local.properties').newDataInputStream())

        maven {
            setUrl("https://asia-southeast1-maven.pkg.dev/teko-development/teko-mobile-sdks")

            authentication {
                basic(BasicAuthentication)
            }

            credentials {
                username = "_json_key_base64"
                password = properties.getProperty('TekoGoogleRegistry.password')
            }
        }
    }
}

iOS 配置

在终端中设置 GitHub 访问令牌以访问 Teko iOS 框架(联系 trung.cs@teko.vn 获取):

touch ~/.bash_profile; open ~/.bash_profile

在打开的文件中添加以下行:

export GITHUB_USER_TOKEN="<your-token>"

保存文件并运行:

source ~/.bash_profile

使用 Apollo 客户端

以下是完整的示例代码,展示了如何初始化 Apollo 客户端,并获取主题颜色。

示例代码

import 'package:apollo_flutter/apollo_theme.dart';
import 'package:apollo_flutter/terra_apollo.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  ApolloColorTheme? _colorTheme;

  // 初始化 Apollo 客户端
  void _initApollo() async {
    final apollo = await TerraApollo.getInstance("apollo-flutter");
    setState(() {
      _colorTheme = apollo.getTheme().colors;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Apollo Flutter 示例应用'),
        ),
        body: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            TextButton(
              onPressed: _initApollo,
              child: const Text(
                '初始化 Apollo',
              ),
            ),
            if (_colorTheme != null) ColorThemeView(colorTheme: _colorTheme!)
          ],
        ),
      ),
    );
  }
}

class ColorThemeView extends StatelessWidget {
  final ApolloColorTheme colorTheme;

  const ColorThemeView({Key? key, required this.colorTheme}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Expanded(
      child: SingleChildScrollView(
        child: Column(
          children: [
            ColorSetView(name: "primary", colorSet: colorTheme.primary),
            ColorSetView(name: "link", colorSet: colorTheme.link),
            ColorSetView(name: "pending", colorSet: colorTheme.pending),
            ColorSetView(name: "success", colorSet: colorTheme.success),
            ColorSetView(name: "error", colorSet: colorTheme.error),
            NeutralColorSetView(colorSet: colorTheme.neutral)
          ],
        ),
      ),
    );
  }
}

class ColorSetView extends StatelessWidget {
  final String name;
  final ApolloColorSet colorSet;

  const ColorSetView({Key? key, required this.name, required this.colorSet}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            name,
            style: const TextStyle(fontWeight: FontWeight.bold),
          ),
          IntrinsicHeight(
            child: Row(
              children: [
                ColorItemView(name: "50", color: colorSet.color50),
                ColorItemView(name: "100", color: colorSet.color100),
                ColorItemView(name: "200", color: colorSet.color200),
                ColorItemView(name: "500", color: colorSet.color500),
                ColorItemView(name: "600", color: colorSet.color600),
                ColorItemView(name: "700", color: colorSet.color700),
              ],
            ),
          ),
          const SizedBox(height: 24),
        ],
      ),
    );
  }
}

class NeutralColorSetView extends StatelessWidget {
  final ApolloNeutralColorSet colorSet;

  const NeutralColorSetView({Key? key, required this.colorSet}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Text(
            "Neutral",
            style: TextStyle(fontWeight: FontWeight.bold),
          ),
          IntrinsicHeight(
            child: Row(
              children: [
                ColorItemView(name: "white", color: colorSet.white),
                ColorItemView(name: "tableHeader", color: colorSet.tableHeader),
                ColorItemView(name: "background", color: colorSet.background),
                ColorItemView(name: "divider", color: colorSet.divider),
                ColorItemView(name: "disable", color: colorSet.disable),
                ColorItemView(name: "border", color: colorSet.border),
                ColorItemView(name: "placeholder", color: colorSet.placeholder),
                ColorItemView(name: "secondaryText", color: colorSet.secondaryText),
                ColorItemView(name: "titleText", color: colorSet.titleText),
              ],
            ),
          ),
          const SizedBox(height: 24),
        ],
      ),
    );
  }
}

class ColorItemView extends StatelessWidget {
  final String name;
  final Color color;

  const ColorItemView({Key? key, required this.name, required this.color}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Expanded(
      child: Column(
        children: [
          Container(
            height: 60,
            color: color,
          ),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 4.0),
            child: Text(name),
          ),
        ],
      ),
    );
  }
}

更多关于Flutter Apollo GraphQL 客户端插件apollo_flutter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Apollo GraphQL 客户端插件apollo_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


apollo_flutter 是一个用于在 Flutter 应用中与 GraphQL API 进行交互的客户端插件。它基于 Apollo Client,提供了强大的功能和灵活的 API 来管理 GraphQL 查询、突变和订阅。

以下是使用 apollo_flutter 的基本步骤:

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  apollo_flutter: ^3.0.0  # 请使用最新版本

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

2. 创建 Apollo 客户端

在 Flutter 应用中,你需要创建一个 ApolloClient 实例来与 GraphQL API 进行交互。通常,你可以在应用的顶层(例如 main.dart 文件中)创建并配置这个客户端。

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

void main() {
  final HttpLink httpLink = HttpLink(
    'https://your-graphql-endpoint.com/graphql',
  );

  final ApolloClient apolloClient = ApolloClient(
    link: httpLink,
    cache: InMemoryCache(),
  );

  runApp(MyApp(apolloClient: apolloClient));
}

class MyApp extends StatelessWidget {
  final ApolloClient apolloClient;

  MyApp({required this.apolloClient});

  @override
  Widget build(BuildContext context) {
    return ApolloProvider(
      client: apolloClient,
      child: MaterialApp(
        title: 'Flutter Apollo Example',
        home: HomeScreen(),
      ),
    );
  }
}

3. 使用 GraphQL 查询

你可以使用 Query 小部件来执行 GraphQL 查询并显示结果。

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

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('GraphQL Example'),
      ),
      body: Query(
        options: QueryOptions(
          document: gql(r'''
            query GetBooks {
              books {
                title
                author
              }
            }
          '''),
        ),
        builder: (QueryResult result, {VoidCallback? refetch, FetchMore? fetchMore}) {
          if (result.hasException) {
            return Text(result.exception.toString());
          }

          if (result.isLoading) {
            return Center(child: CircularProgressIndicator());
          }

          final List<dynamic> books = result.data?['books'] ?? [];

          return ListView.builder(
            itemCount: books.length,
            itemBuilder: (context, index) {
              final book = books[index];
              return ListTile(
                title: Text(book['title']),
                subtitle: Text(book['author']),
              );
            },
          );
        },
      ),
    );
  }
}

4. 使用 GraphQL 突变

你可以使用 Mutation 小部件来执行 GraphQL 突变。

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

class AddBookScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Add Book'),
      ),
      body: Mutation(
        options: MutationOptions(
          document: gql(r'''
            mutation AddBook($title: String!, $author: String!) {
              addBook(title: $title, author: $author) {
                title
                author
              }
            }
          '''),
        ),
        builder: (
          RunMutation runMutation,
          QueryResult? result,
        ) {
          final TextEditingController titleController = TextEditingController();
          final TextEditingController authorController = TextEditingController();

          return Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              children: [
                TextField(
                  controller: titleController,
                  decoration: InputDecoration(labelText: 'Title'),
                ),
                TextField(
                  controller: authorController,
                  decoration: InputDecoration(labelText: 'Author'),
                ),
                SizedBox(height: 20),
                ElevatedButton(
                  onPressed: () {
                    runMutation({
                      'title': titleController.text,
                      'author': authorController.text,
                    });
                  },
                  child: Text('Add Book'),
                ),
                if (result != null && result.isLoading)
                  Center(child: CircularProgressIndicator()),
                if (result != null && result.hasException)
                  Text(result.exception.toString()),
                if (result != null && result.data != null)
                  Text('Book added successfully!'),
              ],
            ),
          );
        },
      ),
    );
  }
}

5. 使用 GraphQL 订阅

你可以使用 Subscription 小部件来订阅 GraphQL 事件。

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

class BookUpdatesScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Book Updates'),
      ),
      body: Subscription(
        options: SubscriptionOptions(
          document: gql(r'''
            subscription OnBookAdded {
              bookAdded {
                title
                author
              }
            }
          '''),
        ),
        builder: (QueryResult result) {
          if (result.hasException) {
            return Text(result.exception.toString());
          }

          if (result.isLoading) {
            return Center(child: CircularProgressIndicator());
          }

          final dynamic book = result.data?['bookAdded'];

          return ListTile(
            title: Text(book['title']),
            subtitle: Text(book['author']),
          );
        },
      ),
    );
  }
}

6. 处理缓存

ApolloClient 默认使用 InMemoryCache 来缓存查询结果。你可以通过配置缓存策略来优化应用的性能。

final ApolloClient apolloClient = ApolloClient(
  link: httpLink,
  cache: InMemoryCache(
    dataIdFromObject: (object) => object['id'], // 自定义缓存键
  ),
);

7. 错误处理

你可以通过检查 QueryResulthasException 属性来处理错误。

if (result.hasException) {
  return Text(result.exception.toString());
}
回到顶部