2017-07-26 7 views
1

私のアプリケーションのページ間をナビゲートするTabBarViewがあります。別々のページごとにAppBarを作成するのではなく、現在表示されているページに基づいてメイン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(), 

      ], 
     ), 
    ); 
    }  

答えて

1

は私が

を推測テキストや色の変化のためのサポートを追加するには、このコードを修正しました

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に似ているので、私は少しイライラしていたウィジェットを変更しました必要です。私の上記のコードとどのようなOPが望んでいたとの唯一の違いは、私は正確に何をするかページクラスを理解していないコード

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'), 
    ); 
    } 
} 
+0

これは、経路の定義とそれとどのように違うのですか?そしてそれらへのナビゲートは、それぞれの選択肢が実際の経路/ページとして扱われますか? – aziza

+0

次回は、ナビゲーションとルートクラスを使用してページにタブを表示するように書いてください。私はあなたのためのソリューションを必要とする場合は、コードを参照する必要があります。 タブ付きバーサンプルを使用して、グローバル親状態を設定してマテリアルカラーを変更する方法を示しました。各ChoiceCardはウィジェットですが、必要に応じて新しいページのように動作します。変更する必要があるのは、ChoiceCardクラスだけです。ケースステートメントを追加してビルドのページを返します。 タブバーウィジェットを使用している場合は、オンフレッドコールバックを変更して、現在状態を設定しているページを特定できます。 – user1462442

+0

自分のコードで投稿を更新しました。 – aziza

2

あなたがPageViewの代わりに使用している場合TabBarViewの場合は、onPageChanged関数を指定して状態を変更できるため、ウィジェットを再構築することができます。ここで

は、タイトルがアプリケーションバーに変更され、私が働いているいくつかのコードですが、コンセプトは基本的に同じです。

// 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, 
    ), 
    ); 
    } 
} 
+0

である代わりに、ボタン自体ここ

のtabcontrollerに変更に追加したことです? – aziza

+0

また、このメソッドは何をしますか? CalendarView.page() – aziza

+0

ページクラスについて心配する必要はなく、それぞれの "ページ"のデータを保持しています。 CalendarView.page()は静的メソッドで、作成したCalendarViewのページを返します。 –

関連する問題