Flutter kit --- Code page switching state holding

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/hekaiyou/article/details/89471457

A normal Flutter project through the bottom of the navigation bar ( BottomNavigationBar) or a label field ( TabBarto switch the page content) components, operation is normal. But whether we have found that every time the navigation bar or tab bar when switching pages, the page before it was cleaned up. For example, the first page of the list view ( ListView) has been slid in the end portion, and then switch back to a second page after the first page of the list back to the top.

The reason for the above problem is that state of the page ( State) has not been preserved, so each page will initialize a state. We can automatically maintain an active client mix ( AutomaticKeepAliveClientMixin) abstract class to solve this problem.

The first is to create a new dart file, the shelves Flutter applications and pages take up, and then run the debugger, make sure the application can be up and running properly.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(title: 'Flutter Demo 主页'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // TODO:当前页面视图的相关变量。

  // TODO:切换页面视图的方法。

  // TODO:集中管理导航项目列表和页面组件列表。

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // TODO:页面视图的主要内容。
    );
  }
}

Here then create a dart file, the navigation page component corresponding to the entry, and then placed inside a list view ( ListView) assembly, whether used to achieve the latter experiment code state holding the page ( State).

Automatically maintain active client mix ( AutomaticKeepAliveClientMixin) abstract class, is automatically maintained active ( AutomaticKeepAliveto provide a method that can be used directly, the state () of the client State) with the use of a subclass can be avoided as a page view parent element ( PageView) when the switching component is repaint.

Automatically maintain active client mix ( AutomaticKeepAliveClientMixin) abstract class and want to maintain activity ( wantKeepAlive) attribute for setting whether the current instance should be kept active by the switching parent component does not re-drawn. This step is critical.

/// 自定义的导航页面组件。
class NavigationPage extends StatefulWidget {
  @override
  _NavigationPageState createState() => _NavigationPageState();
}

/// 与自定义的导航页面组件关联的状态子类。
class _NavigationPageState extends State<NavigationPage>
    with AutomaticKeepAliveClientMixin {

  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
      body: ListView.builder(
        padding: EdgeInsets.all(8.0),
        itemExtent: 20.0,
        itemBuilder: (BuildContext context, int index) {
          return Text('项目 $index');
        },
      ),
    );
  }
}

Next step is to configure the bottom of the navigation bar ( BottomNavigationBar) project components ( items) list of items required attributes, as well as the corresponding page components.

  // TODO:集中管理导航项目列表和页面组件列表。
  /// 统一管理导航项目的列表。
  List<BottomNavigationBarItem> navigationItem = [
    BottomNavigationBarItem(
      icon: Icon(Icons.home),
      title: Text('首页'),
    ),
    BottomNavigationBarItem(
      icon: Icon(Icons.comment),
      title: Text('消息'),
    ),
    BottomNavigationBarItem(
      icon: Icon(Icons.settings),
      title: Text('设置'),
    ),
  ];

  /// 统一管理导航项目对应的组件列表。
  final _widgetOptions = [
    NavigationPage(),
    NavigationPage(),
    NavigationPage(),
  ];

Then define what page views ( PageViewselecting the index components, controllers and resources) release function.

  // TODO:当前页面视图的相关变量。
  /// 当前页面选择的索引。
  int _selectedIndex = 0;

  /// 页面控制器(`PageController`)组件,页面视图(`PageView`)的控制器。
  PageController _controller = PageController();

  /// 释放相关资源。
  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

Because we are using to view the page ( PageView) component, and the page view component does not automatically switch pages, so we have to write about their own method of switching pages.

  // TODO:切换页面视图的方法。
  void _onItemTapped(int index) {
    // 创建底部导航栏的组件需要跟踪当前索引并调用`setState`以使用新提供的索引重建它。
    setState(() {
      _selectedIndex = index;
      // 跳到页面(`jumpToPage`)方法,更改显示在的页面视图(`PageView`)组件中页面。
      _controller.jumpToPage(index);
    });
  }

Scaffolding finalize ( Scaffoldthe main content of the component), the contents of the above are useful.

      // TODO:页面视图的主要内容。
      // 页面视图(`PageView`)组件,可逐页工作的可滚动列表,每个子项都被强制与视窗大小相同。
      body: PageView.builder(
        // 物理(`physics`)属性,页面视图应如何响应用户输入。
        // 从不可滚动滚动物理(`NeverScrollableScrollPhysics`)类,不允许用户滚动。
        physics: NeverScrollableScrollPhysics(),
        itemBuilder: (BuildContext context, int index) {
          return _widgetOptions.elementAt(index);
        },
        itemCount: _widgetOptions.length,
        // 控制器(`controller`)属性,用于控制滚动此页面视图位置的对象。
        controller: _controller,
      ),
      // 底部导航栏(`bottomNavigationBar`)属性,显示在脚手架(`Scaffold`)组件的底部。
      // 底部导航栏(`BottomNavigationBar`)组件,显示在应用程序底部的组件,
      // 用于在几个屏幕之间中进行选择,通常在三到五之间,再多就不好看了。
      bottomNavigationBar: BottomNavigationBar(
        // 项目(`items`)属性,位于底部导航栏中的交互组件,其中每一项都有一个图标和标题。
        items: navigationItem,
        // 目前的索引(`currentIndex`)属性,当前活动项的项目索引。
        currentIndex: _selectedIndex,
        // 固定颜色(`fixedColor`)属性,当BottomNavigationBarType.fixed时所选项目的颜色。
        fixedColor: Color(0xffFE7C30),
        // 在点击(`onTap`)属性,点击项目时调用的回调。
        onTap: _onItemTapped,
        // 定义底部导航栏(`BottomNavigationBar`)组件的布局和行为。
        type: BottomNavigationBarType.fixed,
      ),

Run the code to achieve the effect as the image below.

State of the page is held down

Guess you like

Origin blog.csdn.net/hekaiyou/article/details/89471457