Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
281 views
in Technique[技术] by (71.8m points)

android - How can I have my AppBar in a separate file in Flutter while still having the Widgets show?

I am currently building a Flutter app that recommends restaurants around the area. However, I've gotten myself in quite the kerfuffle.

I want my app to have the code for the AppBar separate from the code for each screen for the sake of organization and cleanliness. So, I built KainAppBar.dart as the AppBar code. It is shown here:

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('guestemail@email.com'),
            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>[
            ],
          ),
        )
      ],
    ),

    );

  }
}

For some of my screens, I can declare it with no problem. Here is the code for 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");

      }
    }

However, for my restaurant_screen.dart, I've encountered a problem. For context, what restaurant_screen.dart does is it shows the restaurants included in the app through a TabBar with three options(tabs): Restaurant List, Cuisine List, and History. Which means that apart from the AppBar, it also needs to have a TabBar inside. But I cannot put this TabBar inside KainAppBar.dart because I only need it to show inside restaurant_screen.dart.

Here is my code for the Widget inside 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(),
                  ],
              ),
      ],
    );
  }

Running the code just shows a black screen. Is there any workaround for this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is another way of going about it. By doing this you can customize this appbar to the way you want. That way, if you continue with that style, you don't have to recreate it on every page. You create it once and call on it within any widget.

Class

import 'package:flutter/material.dart';

class BaseAppBar extends StatelessWidget implements PreferredSizeWidget {
  final Color backgroundColor = Colors.red;
  final Text title;
  final AppBar appBar;
  final List<Widget> widgets;

  /// you can add more fields that meet your needs

  const BaseAppBar({Key key, this.title, this.appBar, this.widgets})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return AppBar(
      title: title,
      backgroundColor: backgroundColor,
      actions: widgets,
    );
  }

  @override
  Size get preferredSize => new Size.fromHeight(appBar.preferredSize.height);
}

Implementation within desired page

@override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: BaseAppBar(
          title: Text('title'),
          appBar: AppBar(),
          widgets: <Widget>[Icon(Icons.more_vert)],
        ),
        body: Container());
  }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...