Flutter页面保活插件keep_alive_builder的使用

Flutter页面保活插件keep_alive_builder的使用

特性

Keep alive for FutureBuilder and StreamBuilder

在Flutter中,keep_alive_builder 插件可以帮助你实现 FutureBuilderStreamBuilder 的页面保活功能。这意味着当这些构建器不在屏幕视图中时,它们的状态会被保留下来,从而避免不必要的重建。

示例代码

以下是一个完整的示例,展示了如何使用 keep_alive_builder 插件来保活 FutureBuilderKeepAliveFutureBuilder

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _count1 = 1;
  int _count2 = 1;

  @override
  Widget build(BuildContext context) {
    const gap = SizedBox(height: 40);
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: SizedBox(
        width: double.infinity,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            gap,
            FutureBuilder<int>(
              future: Future(() async {
                await Future.delayed(
                  const Duration(seconds: 1),
                );
                return _count1;
              }),
              builder: (context, snapshot) {
                if (snapshot.hasError) {
                  return const Text('error');
                }
                if (snapshot.connectionState != ConnectionState.done) {
                  return const Text('loading...');
                }

                return Text('future builder: ${snapshot.data}');
              },
            ),
            gap,
            // 使用 KeepAliveFutureBuilder 保持状态
            KeepAliveFutureBuilder<int>(
              needLoadingForSubsequentRequests: false,
              refreshKey: ValueKey(_count2),
              futureGenerator: () => Future(() async {
                    await Future.delayed(
                      const Duration(seconds: 1),
                    );
                    return _count2;
                  }),
              loading: const Text('loading...'),
              builder: (value) {
                return Text('keep alive future builder: $value');
              },
            ),
            gap,
            TextButton(
              onPressed: () {
                setState(() {
                  _count1++;
                  _count2++;
                });
              },
              child: const Text('rebuild'),
            ),
          ],
        ),
      ),
    );
  }
}

代码解释

  1. 导入必要的库

    import 'package:flutter/material.dart';
    import 'package:keep_alive_builder/keep_alive_builder.dart';
    
  2. 定义主应用

    void main() {
      runApp(const MyApp());
    }
    
  3. 创建 MyApp

    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
  4. 创建 MyHomePage

    class MyHomePage extends StatefulWidget {
      const MyHomePage({super.key, required this.title});
      final String title;
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
  5. 定义 _MyHomePageState

    class _MyHomePageState extends State<MyHomePage> {
      int _count1 = 1;
      int _count2 = 1;
    
      @override
      Widget build(BuildContext context) {
        const gap = SizedBox(height: 40);
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: SizedBox(
            width: double.infinity,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                gap,
                FutureBuilder<int>(
                  future: Future(() async {
                    await Future.delayed(
                      const Duration(seconds: 1),
                    );
                    return _count1;
                  }),
                  builder: (context, snapshot) {
                    if (snapshot.hasError) {
                      return const Text('error');
                    }
                    if (snapshot.connectionState != ConnectionState.done) {
                      return const Text('loading...');
                    }
    
                    return Text('future builder: ${snapshot.data}');
                  },
                ),
                gap,
                // 使用 KeepAliveFutureBuilder 保持状态
                KeepAliveFutureBuilder<int>(
                  needLoadingForSubsequentRequests: false,
                  refreshKey: ValueKey(_count2),
                  futureGenerator: () => Future(() async {
                        await Future.delayed(
                          const Duration(seconds: 1),
                        );
                        return _count2;
                      }),
                  loading: const Text('loading...'),
                  builder: (value) {
                    return Text('keep alive future builder: $value');
                  },
                ),
                gap,
                TextButton(
                  onPressed: () {
                    setState(() {
                      _count1++;
                      _count2++;
                    });
                  },
                  child: const Text('rebuild'),
                ),
              ],
            ),
          ),
        );
      }
    }
    

更多关于Flutter页面保活插件keep_alive_builder的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter页面保活插件keep_alive_builder的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter应用中使用keep_alive_builder插件来保持页面活跃的示例代码。keep_alive_builder是一个常用的插件,用于防止页面在导航堆栈中被销毁,从而保持页面状态。

首先,确保你已经在pubspec.yaml文件中添加了keep_alive_provider依赖(假设keep_alive_builderkeep_alive_provider的一部分,因为没有一个直接叫做keep_alive_builder的官方插件,但概念类似):

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

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

接下来,让我们编写一个示例代码,展示如何使用KeepAliveBuilder来保持页面活跃。

主应用入口(main.dart

import 'package:flutter/material.dart';
import 'package:keep_alive_provider/keep_alive_provider.dart';
import 'page_one.dart';
import 'page_two.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Navigator(
        initialRoute: '/',
        onGenerateRoute: (RouteSettings settings) {
          switch (settings.name) {
            case '/':
              return MaterialPageRoute(builder: (_) => PageOne());
            case '/page_two':
              return MaterialPageRoute(builder: (_) => PageTwo());
            default:
              return MaterialPageRoute(builder: (_) => Scaffold(body: Center(child: Text('404 Not Found'))));
          }
        },
      ),
    );
  }
}

第一个页面(page_one.dart

import 'package:flutter/material.dart';
import 'package:keep_alive_provider/keep_alive_provider.dart';
import 'page_two.dart';

class PageOne extends StatefulWidget {
  @override
  _PageOneState createState() => _PageOneState();
}

class _PageOneState extends State<PageOne> with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true; // 表示我们希望这个页面保持活跃

  @override
  Widget build(BuildContext context) {
    super.build(context); // 调用super.build(context)来通知Flutter框架此Widget希望保持活跃

    return Scaffold(
      appBar: AppBar(
        title: Text('Page One'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You are in Page One',
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            KeepAliveBuilder(
              builder: (context) => ElevatedButton(
                onPressed: () {
                  Navigator.pushNamed(context, '/page_two');
                },
                child: Text('Go to Page Two'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

第二个页面(page_two.dart

import 'package:flutter/material.dart';

class PageTwo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Page Two'),
      ),
      body: Center(
        child: Text('You are in Page Two'),
      ),
    );
  }
}

解释

  1. main.dart:定义了一个简单的导航结构,有两个页面:PageOnePageTwo
  2. PageOne:使用AutomaticKeepAliveClientMixin并覆盖wantKeepAlive方法返回true,表示希望该页面保持活跃。同时,在build方法中调用super.build(context)来通知Flutter框架。
  3. KeepAliveBuilder:在PageOne中使用KeepAliveBuilder包裹一个按钮,这样即使页面在后台,按钮的状态也不会丢失。
  4. PageTwo:一个简单的页面,用于演示导航。

这个示例展示了如何使用keep_alive_provider(或类似插件)和AutomaticKeepAliveClientMixin来保持Flutter页面活跃。请注意,实际插件名称和用法可能会有所不同,但核心思想是类似的。

回到顶部