我有一个TabBarView,可以在我的应用中的页面之间导航。有没有办法根据当前查看的页面更改/覆盖主AppBar的文本和颜色,而不是分别为每个页面创建一个AppBar?
这就是我的网页设置方式
我的路线在主要功能中定义如下:
routes: <String, WidgetBuilder>{
"/Home": (BuildContext context) => new first.Home(),
"/Support": (BuildContext context) => new second.Support(),
}
标签类
class Tabs extends StatefulWidget {
@override
TabsState createState() => new TabsState();
}
class TabsState extends State<Tabs> with SingleTickerProviderStateMixin {
TabController controller;
@override
void initState() {
super.initState();
controller = new TabController(length: 5, vsync: this);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
centerTitle: true,
title: new Text('App'), backgroundColor: Colors.blue,
bottom: new TabBar(
controller: controller,
tabs: <Tab>[
new Tab (icon: new Icon(Icons.home), text: 'Home',),
new Tab (icon: new Icon(Icons.mail), text:'Support'),
]),
),
body: new TabBarView(
controller: controller,
children: <Widget>[
new first.Home(),
new second.Support(),
],
),
);
}
答案 0 :(得分:4)
如果您使用PageView
而不是TabBarView
,则可以指定允许您更改状态的onPageChanged
函数,从而重建窗口小部件。
以下是我正在处理的一些代码,标题在appbar中已更改,但概念基本相同:
// Copyright 2017 <Abhi Agarwal>
// Refer to LICENSE
// Dart Imports
// Flutter Imports
import 'package:flutter/material.dart';
// Package Imports
import 'package:shared_preferences/shared_preferences.dart'
show SharedPreferences;
// Local Imports
import '../calendar/calendar_view.dart' show CalendarView;
import '../error/error_screen.dart' show ErrorScreen;
import '../homework/homework_view.dart' show HomeworkView;
import '../loading/loading_screen.dart' show LoadingScreen;
import 'page.dart' show Page;
class MainView extends StatefulWidget {
MainView({Key key, this.initialIndex = 0, SharedPreferences prefs})
: pages = _makePagesList(prefs),
super(key: key);
final int initialIndex;
final List<Page> pages;
static List<Page> _makePagesList(SharedPreferences prefs) => <Page>[
CalendarView.page(),
new Page(
page: new ErrorScreen(error: "Hello World"),
title: "Schedule",
iconData: Icons.schedule,
),
HomeworkView.page(),
new Page(
page: new LoadingScreen(),
title: "Settings",
iconData: Icons.settings,
),
];
@override
_MainViewState createState() => new _MainViewState();
}
class _MainViewState extends State<MainView> {
PageController _controller;
int _index;
@override
void initState() {
super.initState();
_controller = new PageController(initialPage: widget.initialIndex);
_index = widget.initialIndex;
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
void _handlePageChange(int index) => setState(() => _index = index);
void _navigateToPage(int index) => _controller.animateToPage(
index,
duration: const Duration(milliseconds: 300),
curve: Curves.ease,
);
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(
widget.pages[_index].title,
style: new TextStyle(
fontFamily: Theme.of(context).textTheme.title.fontFamily,
),
),
backgroundColor: Theme.of(context).primaryColor,
),
bottomNavigationBar: new BottomNavigationBar(
type: BottomNavigationBarType.shifting,
items: widget.pages
.map((Page page) => new BottomNavigationBarItem(
icon: new Icon(
page.iconData,
color: Theme.of(context).primaryColor,
),
title: new Text(
page.title,
style: new TextStyle(
color: Theme.of(context).primaryColor,
),
),
backgroundColor: Theme.of(context).canvasColor,
))
.toList(),
onTap: _navigateToPage,
currentIndex: _index,
),
floatingActionButton: widget.pages[_index].useFab
? new FloatingActionButton(
tooltip: widget.pages[_index].tooltip,
child: widget.pages[_index].fab,
onPressed: () => widget.pages[_index].onPressed(context),
)
: null,
body: new PageView(
controller: _controller,
children: widget.pages.map((Page page) => page.page).toList(),
onPageChanged: _handlePageChange,
),
);
}
}
答案 1 :(得分:3)
我修改了此代码以添加对文本和颜色更改的支持我猜
https://flutter.io/catalog/samples/tabbed-app-bar/
我为代码的丑陋道歉。我所做的只是将所有类更改为有状态小部件,添加一个setstate图标选择器,更改小部件以便有一个onPressed回调
import 'package:flutter/material.dart';
class MainApp extends StatefulWidget {
MainApp({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful,
// meaning that it has a State object (defined below) that contains
// fields that affect how it looks.
// This class is the configuration for the state. It holds the
// values (in this case the title) provided by the parent (in this
// case the App widget) and used by the build method of the State.
// Fields in a Widget subclass are always marked "final".
final String title;
@override
TabbedAppBarSample createState() => new TabbedAppBarSample();
}
class TabbedAppBarSample extends State<MainApp> {
Choice _choice;
initState(){
super.initState();
_choice = choices[0];
}
void _select(var c){
setState((){
_choice = c;
});
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new DefaultTabController(
length: choices.length,
child: new Scaffold(
appBar: new AppBar(
//dynamically create appbar colors
backgroundColor: new Color(_choice.color),
title: new Text(_choice.title),
bottom: new TabBar(
isScrollable: true,
tabs: choices.map((Choice choice) {
//change to iconbutton
return new IconButton(
icon: new Icon(choice.icon),
onPressed: (){_select(choice);},
);
}).toList(),
),
),
body:
new TabBarView(
children: choices.map((Choice choice) {
return new Padding(
padding: const EdgeInsets.all(16.0),
child: new ChoiceCard(choice: choice),
);
}).toList(),
),
),
),
);
}
}
class Choice {
const Choice({ this.title, this.icon, this.color});
final String title;
final IconData icon;
final num color;
}
const List<Choice> choices = const <Choice>[
const Choice(title: 'CAR', icon: Icons.directions_car, color: 0xFFE0F7FA),
const Choice(title: 'BICYCLE', icon: Icons.directions_bike, color: 0x00ff0000),
const Choice(title: 'BOAT', icon: Icons.directions_boat, color: 0xFF42A5F5),
const Choice(title: 'BUS', icon: Icons.directions_bus, color: 0x0),
const Choice(title: 'TRAIN', icon: Icons.directions_railway, color: 0xFFEFFFFF),
const Choice(title: 'WALK', icon: Icons.directions_walk, color: 0x0000ff00),
];
class ChoiceCard extends StatefulWidget {
ChoiceCard({Key key, this.choice}) : super(key: key);
final Choice choice;
@override
_ChoiceCard createState() => new _ChoiceCard();
}
class _ChoiceCard extends State<ChoiceCard> {
@override
Widget build(BuildContext context) {
final TextStyle textStyle = Theme.of(context).textTheme.display1;
return new Card(
color: Colors.white,
child: new Center(
child: new Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Icon(widget.choice.icon, size: 128.0, color: textStyle.color),
new Text(widget.choice.title, style: textStyle),
],
),
),
);
}
}
void main() {
runApp(new MainApp());
}
我有点生气,因为上面的代码与op所需的实际答案类似。我上面的代码和操作系统想要的唯一区别是我将更改添加到tabcontroller而不是按钮本身
这是代码
import 'package:flutter/material.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget{
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Nothing',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new Tabs(),
);
}
}
class Tabs extends StatefulWidget {
@override
TabsState createState() => new TabsState();
}
class TabsState extends State<Tabs> with SingleTickerProviderStateMixin {
TabController controller;
//create internal state
Choice _choice;
@override
void initState() {
super.initState();
//try to make the length to
controller = new TabController(length: 5, vsync: this);
//add listener to add change index callback
//https://docs.flutter.io/flutter/material/TabController-class.html
controller.addListener(_select);
_choice = choices[0];
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
void _select(){
setState((){
_choice = choices[controller.index];
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
centerTitle: true,
title: new Text(_choice.title), backgroundColor: new Color(_choice.color),
bottom: new TabBar(
controller: controller,
tabs: <Tab>[
new Tab( icon: new Icon(choices[0].icon), text: 'Home',),
new Tab (icon: new Icon(choices[1].icon), text:'Support'),
]),
),
body: new TabBarView(
controller: controller,
children: <Widget>[
//dummy page
new MyHomePage(),
new Center( child: new Text('dummy page 2')),
],
),
);
}
}
class Choice {
const Choice({ this.title, this.icon, this.color});
final String title;
final IconData icon;
final num color;
}
//create a list
const List<Choice> choices = const <Choice>[
const Choice(title: 'Home', icon: Icons.home, color: 0x0),
const Choice(title: 'Support', icon: Icons.mail, color: 0xFF42A5F5),
];
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Center(
child: new Text('dummy page'),
);
}
}
答案 2 :(得分:0)
只需通过if-else检查或切换选项卡的当前索引并执行操作
switch (_tabController.index) {
case 0:
// Do something for Tab 1
break;
case 1:
// Do something for Tab 1
break;
case 2:
// Do something for Tab 1
break;
case 3:
// Do something for Tab 1
break;
case 4:
// Do something for Tab 1
break;
}
每次更改应用程序栏时都需要执行此检查。 这可能不是最好的方法,但是可以。