web-dev-qa-db-ja.com

ウィジェットを表示したまま、AppBarをFlutterの別のファイルに含めるにはどうすればよいですか?

現在、周辺のレストランを推奨するFlutterアプリを作成しています。しかし、私はかなりの乱闘に身を任せています。

私は、整理と清潔さのために、アプリにAppBarのコードを各画面のコードとは別にしたいと考えています。そこで、AppBarコードとしてKainAppBar.Dartを作成しました。以下に示します。

import 'package:flutter/material.Dart';
import 'package:gradient_app_bar/gradient_app_bar.Dart';
import 'package:firebase_auth/firebase_auth.Dart';
import 'package:google_sign_in/google_sign_in.Dart';

GoogleSignIn _googleSignIn = GoogleSignIn(
  signInOption: SignInOption.standard,
);

class KainAppBar extends StatelessWidget {
  final String title;

  KainAppBar(this.title);

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: new GradientAppBar(
      centerTitle: true,
      title: new Text('Kain',
      style: TextStyle(
        fontFamily: 'Quiapo', fontSize: 36.0, fontWeight: FontWeight.w600
      )),
      backgroundColorStart: Colors.red[400],
      backgroundColorEnd: Colors.red[900],
    ),
    drawer: new Drawer(
      child: ListView(
        children: <Widget>[
          new UserAccountsDrawerHeader(
            decoration: BoxDecoration(
              color: Colors.red[800],
            ),
            accountName: new Text('Guest'),
            accountEmail: new Text('[email protected]'),
            currentAccountPicture: new CircleAvatar(
              backgroundImage: new NetworkImage('https://avatarfiles.alphacoders.com/848/84855.jpg'),
            ),
          ),
          new ListTile(
            title: new Text('Restaurants'),
            leading: Icon(Icons.restaurant_menu),
            onTap: (){
              Navigator.of(context).pop();
              Navigator.of(context).pushNamed('/restaurant_screen');
            },
          ),
          new ListTile(
            title: new Text('Nearby'),
            leading: Icon(Icons.near_me),
            onTap: (){
              Navigator.of(context).pop();
              Navigator.of(context).pushNamed('/nearby_screen');
            },
          ),
          new ListTile(
            title: new Text('Request Restaurant'),
            leading: Icon(Icons.library_add),
            onTap: (){
              Navigator.of(context).pop();
              Navigator.of(context).pushNamed('/request_screen');
            },
          ),
          new ListTile(
            title: new Text('Settings'),
            leading: Icon(Icons.settings),
            onTap: (){},
          ),
          new ListTile(
            title: new Text('About'),
            leading: Icon(Icons.info_outline),
            onTap: (){},
          ),
          new ListTile(
            title: new Text('Logout'),
            leading: Icon(Icons.power_settings_new),
            onTap: (){
                  _googleSignIn.disconnect();
              FirebaseAuth.instance.signOut().then((value) {
                    Navigator.of(context).pushReplacementNamed('/login');
                  }).catchError((e) {
                     print(e);
                  });
            },
          ),
        ],
      ),
    ),
     body: new Column(
       crossAxisAlignment: CrossAxisAlignment.center,
       mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Container(
          padding: EdgeInsets.fromLTRB(50.0, 160.0, 50.0, 0.0),
          child: new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
            ],
          ),
        )
      ],
    ),

    );

  }
}

一部の画面では、問題なく宣言できます。これがhome_screen.Dartのコードです。

    class HomeScreen extends StatefulWidget {
      @override
      HomeScreenState createState() {
        return HomeScreenState();
      }
    }

    class HomeScreenState extends State<HomeScreen>{
    @override
      noSuchMethod(Invocation invocation) {
        return super.noSuchMethod(invocation);
      }
    @override
    Widget build(BuildContext context){

      return new KainAppBar("Kain");

      }
    }

ただし、restaurant_screen.Dartの場合、問題が発生しました。コンテキストについては、restaurant_screen.Dartが行うことは、3つのオプション(タブ)を持つTabBarを介してアプリに含まれるレストランを表示することです:レストランリスト、料理リスト、および履歴。つまり、AppBarとは別に、内部にTabBarが必要です。しかし、このタブバーをKainAppBar.Dart内に配置することはできません。これはrestaurant_screen.Dart内に表示することだけが必要だからです。

これがrestaurant_screen.Dart内のウィジェットのコードです。

  @override
  Widget build(BuildContext context) {
    return new Column(
      children: <Widget>[
        GradientAppBar(
          title: KainAppBar("Kain"),
          bottom: new TabBar(
            labelColor: Colors.white,
            controller: tController,
            tabs: <Widget>[
              new Tab(text: 'List'),
              new Tab(text: 'Cuisine'),
              new Tab(text: 'Favorites'),
              ],
              ),
              ),
              TabBarView(
                controller: tController,
                children: <Widget>[
                  new firstpage.RestaurantList(),
                  new secondpage.CuisineList(),
                  new thirdpage.RestaurantFavorites(),
                  ],
              ),
      ],
    );
  }

コードを実行すると、黒い画面が表示されます。これの回避策はありますか?

7

widget.Dart そのようです:

import 'package:flutter/material.Dart';

class ReusableWidgets {
  getAppBar(String title) {
    return AppBar(
      title: Text(title),
    );
  }
}

このクラスを引き続き使用して、すべての画面でappbarを取得します。

import 'package:filter_chip/widgets.Dart';
import 'package:flutter/material.Dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        appBar: new ReusableWidgets().getAppBar('Hello World'),
        body:  Text(
            'Flutter Demo Home Page'), 
      ),
    );
  }
}
1
Ab Sin

AppBarウィジェットを作成する例を以下に示します

import 'package:flutter/material.Dart';

class ListTitleBar extends StatefulWidget implements PreferredSizeWidget {

  final String _left;
  final String _right;

  ListTitleBar(this._left, this._right);

  @override
  State<StatefulWidget> createState() => new ListTitleBarState(_left, _right);

  @override
  Size get preferredSize {
    return new Size.fromHeight(20.0);
  }

}

class ListTitleBarState extends State<ListTitleBar> {

  String _leftTitle;
  String _rightTitle;

  ListTitleBarState(this._leftTitle, this._rightTitle);

  @override
  Widget build(BuildContext context) {

return new Container(

  decoration: new BoxDecoration(
    color: Colors.redAccent,
    border: new Border.all(color: Colors.black),
  ),

  child: new Row(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: <Widget>[

      ///Left Column Title
      new Column(
        children: <Widget>[
          new Container(
            color: Colors.redAccent,
            padding: const EdgeInsets.all(10.0),
            child: new Text(_leftTitle,
              style: new TextStyle(
                  color: Colors.white,
                  fontSize: 18.0
              ),
            ),
          )
        ],
      ),

      ///Right Column Title
      new Column(
        children: <Widget>[
          new Container(
            color: Colors.redAccent,
            padding: const EdgeInsets.all(10.0),
            child: new Text(_rightTitle,
              style: new TextStyle(
                  color: Colors.white,
                  fontSize: 18.0
              ),
            ),
          )
        ],
      ),

    ],
  ),
);

}

@override
void initState() {
  super.initState();
}

 @override
 void dispose() {
   super.dispose();
 }

}
0
Elia Weiss