Flutter网格布局插件apptive_grid_core的使用

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

Flutter网格布局插件apptive_grid_core的使用

ApptiveGrid Core 介绍

ApptiveGrid Core 是一个用于 ApptiveGrid 的核心库,提供了对 ApptiveGrid 功能的一般访问。它还包含了认证和通用客户端逻辑,使您可以构建自己的 ApptiveGrid 体验。

设置

为了使用任何 ApptiveGrid 功能,您必须在应用程序中包裹一个 ApptiveGrid 小部件。

import 'package:apptive_grid_core/apptive_grid_core.dart';

void main() {
  runApp(
    ApptiveGrid(
      options: ApptiveGridOptions(
        environment: ApptiveGridEnvironment.alpha,
        authenticationOptions: ApptiveGridAuthenticationOptions(
          autoAuthenticate: true,
        ),
      ),
      child: MyApp(),
    ),
  );
}

认证

某些功能需要认证。可以通过手动调用 ApptiveGrid.getClient(context).authenticate() 来认证用户。或者,您可以在 ApptiveGridAuthenticationOptions 中将 autoAuthenticate 设置为 true,这将自动触发认证过程。

认证重定向

为了通过认证进行重定向,您需要在 ApptiveGridAuthenticationOptions 中提供一个自定义的 redirectScheme

ApptiveGrid(
  options: ApptiveGridOptions(
    environment: ApptiveGridEnvironment.beta,
    authenticationOptions: ApptiveGridAuthenticationOptions(
      autoAuthenticate: true,
      redirectScheme: 'apptivegrid'
    ),
  ),
  child: MyApp(),
));

确保您的应用程序可以使用该重定向链接打开。有关更多信息,请参阅 uni_links 文档。

Flutter Web

如果您想在 Flutter Web 上使用它,您需要在 runApp 之前调用并等待 enableWebAuth。这将处理认证服务器的重定向。

void main() async {
  await enableWebAuth(options);
  runApp(ApptiveGrid(child: MyApp()));
}
API Key 认证

如果您想使用 API Key 进行认证,可以在 ApptiveGridAuthenticationOptions 中添加一个 ApptiveGridApiKey

ApptiveGridOptions(
  environment: ApptiveGridEnvironment.alpha,
  authenticationOptions: ApptiveGridAuthenticationOptions(
    autoAuthenticate: true,
    apiKey: ApptiveGridApiKey(
      authKey: 'YOUR_AUTH_KEY',
      password: 'YOUR_AUTH_KEY_PASSWORD',
    ),
  )
)

完整示例 Demo

以下是一个完整的示例代码,展示了如何使用 apptive_grid_core 插件来实现网格布局和用户认证功能。

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

/// Add A ApptiveGrid Widget to your Widget Tree to enable ApptiveGrid Functionality
void main() async {
  const options = ApptiveGridOptions(
    environment: ApptiveGridEnvironment.alpha,
    authenticationOptions: ApptiveGridAuthenticationOptions(
      autoAuthenticate: true,
      authGroup: 'apptivegrid',
      redirectScheme: 'apptivegrid',
      persistCredentials: false,
    ),
  );
  await enableWebAuth(options);
  runApp(const ApptiveGrid(options: options, child: MyApp()));
}

/// You can access the ApptiveGridClient via ApptiveGrid.getClient()
class MyApp extends StatefulWidget {
  /// A widget that demonstrates ApptiveGrid functionality
  const MyApp({super.key});

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

class _MyAppState extends State<MyApp> {
  User? _user;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Builder(
        builder: (context) {
          return Scaffold(
            body: ListView(
              children: [
                Text(
                  'User',
                  style: Theme.of(context).textTheme.headlineMedium,
                ),
                _UserSection(
                  onUserLoaded: (user) => setState(() => _user = user),
                ),
                if (_user != null)
                  Text(
                    'Spaces',
                    style: Theme.of(context).textTheme.headlineMedium,
                  ),
                ...(_user?.embeddedSpaces ?? []).map(
                  (e) => _SpaceSection(
                    uri: Uri.parse(
                      e.links[ApptiveLinkType.self]!.uri.toString(),
                    ),
                  ),
                ),
              ],
            ),
          );
        },
      ),
    );
  }
}

class _UserSection extends StatefulWidget {
  const _UserSection({
    required this.onUserLoaded,
  });

  final Function(User) onUserLoaded;

  [@override](/user/override)
  State<_UserSection> createState() => _UserSectionState();
}

class _UserSectionState extends State<_UserSection> {
  Future<User>? _userFuture;
  late ApptiveGridClient _client;

  [@override](/user/override)
  void didChangeDependencies() {
    super.didChangeDependencies();
    _client = ApptiveGrid.getClient(context);
    _reload();
  }

  Future<void> _reload() async {
    _userFuture = _client.getMe().then((value) {
      widget.onUserLoaded(value);
      return value;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return _userFuture != null
        ? FutureBuilder<User>(
            future: _userFuture,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                final user = snapshot.data!;
                return Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        ElevatedButton(
                          child: const Text('Logout'),
                          onPressed: () {
                            ApptiveGrid.getClient(context, listen: false)
                                .logout();
                          },
                        ),
                        IconButton(
                          onPressed: _reload,
                          icon: const Icon(Icons.refresh),
                        ),
                      ],
                    ),
                    Text('${user.firstName} ${user.lastName}'),
                    Text(user.email),
                  ],
                );
              } else if (snapshot.hasError) {
                return Center(
                  child: Text(snapshot.error.toString()),
                );
              } else {
                return const Center(
                  child: CircularProgressIndicator(),
                );
              }
            },
          )
        : const Center(
            child: CircularProgressIndicator(),
          );
  }
}

class _SpaceSection extends StatefulWidget {
  const _SpaceSection({
    required this.uri,
  });

  final Uri uri;

  [@override](/user/override)
  State<_SpaceSection> createState() => _SpaceSectionState();
}

class _SpaceSectionState extends State<_SpaceSection> {
  Future<Space>? _spaceFuture;

  [@override](/user/override)
  void didChangeDependencies() {
    super.didChangeDependencies();
    _spaceFuture = ApptiveGrid.getClient(context).getSpace(
      uri: widget.uri,
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return _spaceFuture != null
        ? FutureBuilder<Space>(
            future: _spaceFuture,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                final space = snapshot.data!;
                return Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(space.name),
                    Column(
                      mainAxisSize: MainAxisSize.min,
                      children: space.embeddedGrids
                              ?.map(
                                (e) => _GridSection(
                                  uri: Uri.parse(
                                    e.links[ApptiveLinkType.self]!.uri
                                        .toString(),
                                  ),
                                ),
                              )
                              .toList() ??
                          [const SizedBox()],
                    ),
                  ],
                );
              } else if (snapshot.hasError) {
                return Center(
                  child: Text(snapshot.error.toString()),
                );
              } else {
                return const Center(
                  child: CircularProgressIndicator(),
                );
              }
            },
          )
        : const Center(
            child: CircularProgressIndicator(),
          );
  }
}

class _GridSection extends StatefulWidget {
  const _GridSection({
    required this.uri,
  });

  final Uri uri;

  [@override](/user/override)
  State<_GridSection> createState() => _GridSectionState();
}

class _GridSectionState extends State<_GridSection> {
  Future<Grid>? _gridFuture;

  [@override](/user/override)
  void didChangeDependencies() {
    super.didChangeDependencies();
    _gridFuture = ApptiveGrid.getClient(context).loadGrid(
      uri: widget.uri,
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return _gridFuture != null
        ? FutureBuilder<Grid>(
            future: _gridFuture,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                final grid = snapshot.data!;
                return Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(grid.name),
                    Column(
                      mainAxisSize: MainAxisSize.min,
                      children: grid.rows
                              ?.map(
                                (e) =>
                                    Text(e.entries.first.data.value.toString()),
                              )
                              .toList() ??
                          [const SizedBox()],
                    ),
                  ],
                );
              } else if (snapshot.hasError) {
                return Center(
                  child: Text(snapshot.error.toString()),
                );
              } else {
                return const Center(
                  child: CircularProgressIndicator(),
                );
              }
            },
          )
        : const Center(
            child: CircularProgressIndicator(),
          );
  }
}

更多关于Flutter网格布局插件apptive_grid_core的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter网格布局插件apptive_grid_core的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用apptive_grid_core插件来创建网格布局的示例代码。apptive_grid_core是一个用于创建响应式和动态网格布局的插件。请确保你已经将该插件添加到你的pubspec.yaml文件中:

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

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

示例代码

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

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

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

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

class _MyHomePageState extends State<MyHomePage> {
  // 网格项数据
  final List<String> items = List.generate(20, (index) => "Item ${index + 1}");

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Apptive Grid Core Example'),
      ),
      body: GridView.builder(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2, // 这里设置每行的列数
          crossAxisSpacing: 4.0,
          mainAxisSpacing: 4.0,
        ),
        itemCount: items.length,
        itemBuilder: (context, index) {
          return GridTile(
            child: Card(
              color: Colors.primary.withOpacity(0.1),
              child: Center(
                child: Text(
                  items[index],
                  style: TextStyle(color: Colors.white, fontSize: 20),
                ),
              ),
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 使用ApptiveGridCore创建动态网格布局
          showDialog(
            context: context,
            builder: (context) {
              return AlertDialog(
                title: Text('Dynamic Grid Example'),
                content: SingleChildScrollView(
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      ApptiveGrid(
                        columnCount: 3, // 动态列数
                        rowCount: 2,    // 动态行数
                        items: items,
                        itemBuilder: (context, index) {
                          return Container(
                            color: Colors.grey.withOpacity(0.5),
                            alignment: Alignment.center,
                            child: Text(
                              items[index],
                              style: TextStyle(color: Colors.white, fontSize: 18),
                            ),
                          );
                        },
                      ),
                    ],
                  ),
                ),
              );
            },
          );
        },
        tooltip: 'Show Dynamic Grid',
        child: Icon(Icons.grid_on),
      ),
    );
  }
}

解释

  1. 基本网格布局

    • 使用GridView.builder创建一个基本的网格布局,每行有两列。
    • gridDelegate设置网格的列数和间距。
    • itemBuilder生成每个网格项的内容。
  2. 动态网格布局

    • 使用ApptiveGrid创建一个动态网格布局,这里设置了3列和2行。
    • itemBuilder生成每个动态网格项的内容。
    • 通过点击浮动按钮(FloatingActionButton)来展示这个动态网格布局。

注意:ApptiveGrid是假设apptive_grid_core插件提供的一个组件,实际使用时请参考该插件的文档,因为不同插件可能会有不同的API设计。如果ApptiveGrid不是apptive_grid_core插件中的实际组件,你可能需要查看插件提供的示例或文档来找到正确的使用方式。

回到顶部