代码之家  ›  专栏  ›  技术社区  ›  Shady Aziza

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

  •  6
  • Shady Aziza  · 技术社区  · 8 年前

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

    我的页面就是这样设置的

    routes: <String, WidgetBuilder>{
                "/Home": (BuildContext context) => new first.Home(),
                "/Support": (BuildContext context) => new second.Support(),
    
              }
    

    Tabs类

            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(),
    
              ],
            ),
          );
        }      
    
    3 回复  |  直到 8 年前
        1
  •  5
  •   Abhi Agarwal    8 年前

    如果您使用 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,
          ),
        );
      }
    }
    
        2
  •  3
  •   user1462442    8 年前

    我修改了这段代码,添加了对文本和颜色更改的支持

    https://flutter.io/catalog/samples/tabbed-app-bar/

      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需要的实际答案相似。我上面的代码与op想要的代码之间的唯一区别是,我将on更改添加到了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'),
         );
       }
     }
    
        3
  •  0
  •   Mhamza007    5 年前

    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;
                }
    

    每次更改应用程序栏时,都需要执行此检查。