Home Articles

根据当前查看的页面更改AppBar的颜色和文本

Asked
Viewed 519 times
4

我有一个TabBarView,可以在我的应用程序中的页面之间导航 . 有没有办法根据当前查看的页面更改/覆盖主AppBar的文本和颜色,而不是分别为每个页面创建一个AppBar?

这就是我的页面设置方式

我的路由在main函数中定义如下:

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(),

          ],
        ),
      );
    }

2 Answers

  • 4

    如果使用 PageView 而不是 TabBarView ,则可以指定允许您更改状态的 onPageChanged 函数,从而重建窗口小部件 .

    这是我正在处理的一些代码, Headers 在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,
          ),
        );
      }
    }
    
  • 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());
      }
    

    我有点恼火,因为我上面的代码类似于操作所需的实际答案 . 我上面的代码和操作系统想要的唯一区别是我将更改添加到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'),
         );
       }
     }
    

Related