PageView 和 BottomNavigationBar 配合使用时 , 在 BottomNavigationBar 切换Tab时 , page 会执行 initState()方法, 导致视图会重新刷新渲染 ,有两种方法 .
1.不使用PageView , 使用IndexedStack存储页面 ,这样会失去PageView 滑动的特效
可以参考 开源中国的 flutter项目 : https://github.com/yubo725/flutter-osc/blob/master/lib/main.dart
children: [
new NewsListPage(),
new TweetsListPage(),
new DiscoveryPage(),
new MyInfoPage()
],
index: _tabIndex,
);
- with AutomaticKeepAliveClientMixin -- wantKeepAlive=>true 保存状态 ,当切换tab时 EventTab就不会重新刷新了
main.dart
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_appa/event_tab.dart';
import 'package:flutter_appa/tablayout.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: MyHome()
);
}
}
class MyHome extends StatefulWidget {
@override
State createState() {
return MyHomeState();
}
}
class MyHomeState extends State with SingleTickerProviderStateMixin {
var _tabIndex = 0;
var _pageController = new PageController(initialPage: 0);
void _pageChange(int index) {
setState(() {
if (_tabIndex != index) {
_tabIndex = index;
}
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: Text("Remind"),
),
body: new PageView.builder(
onPageChanged: _pageChange,
controller: _pageController,
itemBuilder: (BuildContext context, int index) {
return index == 0 ? new EventTab(items: List < String>.generate(10000, (i) => "Item $i")) :
new Tabs(title: "Map");
},
itemCount: 2,
),
bottomNavigationBar: new BottomNavigationBar(
items: [
new BottomNavigationBarItem(
icon: new Icon(Icons.event_note), title: new Text("事件")),
new BottomNavigationBarItem(
icon: new Icon(Icons.alarm), title: new Text("提醒")),
],
currentIndex: _tabIndex,
onTap: (index) {
setState(() {
_tabIndex = index;
});
_pageController.jumpToPage(index);
},
),
);
}
}
EventTab
import 'package:flutter/material.dart';
class EventTab extends StatefulWidget {
final List items;
const EventTab({Key key, @required this.items}) : super(key: key);
@override
State createState() {
return EventTabState();
}
}
class EventTabState extends State with AutomaticKeepAliveClientMixin {
List _items;
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: _items.length,
itemBuilder: (context, index) {
return ListTile(
title: new Text("${_items[index]}"),
);
}
);
}
@override
void initState() {
super.initState();
_items = widget.items;
}
// TODO: implement wantKeepAlive
@override
bool get wantKeepAlive => true;
}
Tabs
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
class Tabs extends StatefulWidget {
final String title;
const Tabs({Key key, @required this.title}) : super(key: key);
@override
State createState() {
return TabsState();
}
}
class TabsState extends State with AutomaticKeepAliveClientMixin {
String _title;
@override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
onPressed: () {
final snackbar = SnackBar(
content: Text(_title),
action: SnackBarAction(
label: "OK",
onPressed: () {
}
),
);
Scaffold.of(context).showSnackBar(snackbar);
},
child: Text(new WordPair.random().asPascalCase)),
);
}
@override
void initState() {
super.initState();
_title = widget.title;
print("tab_init state");
}
// TODO: implement wantKeepAlive
//
@override
bool get wantKeepAlive => true;
}