FlutterFlutter

flutter tab 切换时会导致页面重新加载的解决方案!

2019-06-21  本文已影响0人  换个角度看世界_4b84

最近在用flutter做app的开发,期间遇到了一个问题,就是当使用tab组件当时候,如果跳着点击tab(比如1->3, 2->4,1->1这种点击),则会导致中间当页面重新加载,这种体验十分不友好。

一开始是在网上找当解决方案,让页面 with AutomaticKeepAliveClientMixin, 然后 bool get wantKeepAlive => true; 但是这种方法治标不治本。当你按顺序切换tab的时候,比如 1->2, 2->3, 3->2 时页面确实不会重新加载,但是像我上面描述的1->3, 1->4,4->2 这种跳着切换时,AutomaticKeepAliveClientMixin 就不起作用了,中间的页面还是会重新加载。

于是乎本着探索的精神,终于让我发现了一个相对简单的解决方案,那就是使用 IndexedStack 部件。用这个之后,无论你怎么点击,都能够正确的保持页面的状态,并且dispose的时候,也能够正确的销毁相关组件。以下是示例代码,很简单,大家可以尝试一下:


import 'package:flutter/material.dart';

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

class MyAppextends StatelessWidget {

@override

  Widget build(BuildContext context) {

return MaterialApp(

title:"Don't rebuilt!",

theme:ThemeData(primarySwatch: Colors.blue),

home:FirstPage(),

);

}

}

class FirstPageextends StatelessWidget {

FirstPage({Key key}) :super(key: key);

@override

  Widget build(BuildContext context) {

return Scaffold(

appBar:AppBar(title:Text("I'm the first page")),

body:Center(

child:RaisedButton(

child:Text("go to the tab page"),

onPressed: () => Navigator.of(context).push(

MaterialPageRoute(

builder: (context) =>MyTabPage(),

),

),

),

));

}

}

class MyTabPageextends StatefulWidget {

MyTabPage({Key key}) :super(key: key);

@override

  _MyTabPageState createState() =>_MyTabPageState();

}

class _MyTabPageStateextends Statewith SingleTickerProviderStateMixin {

TabController_tabController;

int_currentTabIndex =0;

List_realPages = [Tab1(),Tab2(),Tab3(),Tab4()];

//lazy init

List_tabPages = [Tab1(),Container(),Container(),Container()];

List_hasInit = [true,false,false,false];

List_tabsButton = [

Tab(child:Text("tab1", style:TextStyle(color: Colors.black))),

Tab(child:Text("tab2", style:TextStyle(color: Colors.black))),

Tab(child:Text("tab3", style:TextStyle(color: Colors.black))),

Tab(child:Text("tab4", style:TextStyle(color: Colors.black))),

];

@override

  void initState() {

print("MyTabPage initState.");

super.initState();

_tabController =TabController(length:_realPages.length, vsync:this)

..addListener(() {

int selectedIndex =_tabController.index;

if (_currentTabIndex != selectedIndex) {

if (!_hasInit[selectedIndex]) {

//lazy init

            _tabPages[selectedIndex] =_realPages[selectedIndex];

_hasInit[selectedIndex] =true;

}

setState(() =>_currentTabIndex = selectedIndex);

}

});

}

@override

  void dispose() {

print("MyTabPage dispose.");

_tabController.dispose();

super.dispose();

}

@override

  Widget build(BuildContext context) {

return Scaffold(

appBar:AppBar(title:Text("Don't rebuilt!")),

body:IndexedStack(index:_currentTabIndex, children:_tabPages),

bottomNavigationBar:TabBar(controller:_tabController, tabs:_tabsButton),

);

}

}

class Tab1extends StatefulWidget {

@override

State createState() {

return _Tab1State();

}

}

class _Tab1Stateextends State {

@override

  void initState() {

super.initState();

print("tab1 initState");

}

@override

  void dispose() {

print("tab1 dispose");

super.dispose();

}

@override

  Widget build(BuildContext context) {

return Scaffold(body:Center(child:Text("I'm tab1")));

}

}

class Tab2extends StatefulWidget {

@override

State createState() {

return _Tab2State();

}

}

class _Tab2Stateextends State {

@override

  void initState() {

super.initState();

print("tab2 initState");

}

@override

  void dispose() {

print("tab2 dispose");

super.dispose();

}

@override

  Widget build(BuildContext context) {

return Scaffold(body:Center(child:Text("I'm tab2")));

}

}

class Tab3extends StatefulWidget {

@override

State createState() {

return _Tab3State();

}

}

class _Tab3Stateextends State {

@override

  void initState() {

super.initState();

print("tab3 initState");

}

@override

  void dispose() {

print("tab3 dispose");

super.dispose();

}

@override

  Widget build(BuildContext context) {

return Scaffold(body:Center(child:Text("I'm tab3")));

}

}

class Tab4extends StatefulWidget {

@override

State createState() {

return _Tab4State();

}

}

class _Tab4Stateextends State {

@override

  void initState() {

super.initState();

print("tab4 initState");

}

@override

  void dispose() {

print("tab4 dispose");

super.dispose();

}

@override

  Widget build(BuildContext context) {

return Scaffold(body:Center(child:Text("I'm tab4")));

}

}


Performing hot reload...

Syncing files to device Android SDK built for x86...

Reloaded 1 of 440 libraries in 284ms.

I/flutter (21209): MyTabPage initState.

I/flutter (21209): tab1 initState

I/flutter (21209): tab3 initState

I/flutter (21209): tab2 initState

I/flutter (21209): tab4 initState

I/flutter (21209): tab1 dispose

I/flutter (21209): tab2 dispose

I/flutter (21209): tab3 dispose

I/flutter (21209): tab4 dispose

I/flutter (21209): MyTabPage dispose.
上一篇下一篇

猜你喜欢

热点阅读