Flutter AppBar PopupMenuButton。想要带弹出的主导图标和带有弹出的右侧图标

时间:2019-10-19 21:06:24

标签: flutter icons appbar popupmenubutton

--> Screenshot Image <--经过数周的教程和其他资源学习后,将Flutter用于第一个项目。将AppBar与前导图标一起使用(左),将PopupMenuButton与图标一起使用(右)。弹出菜单可以正常工作,但是希望在左/前导图标上有一个弹出菜单。

我尝试在右侧的动作小部件下复制代码,但是Flutter不喜欢它。我相信前导图标是有限的,而图标/右侧可以处理更多的小部件/代码。

import 'package:flutter/material.dart';
import 'package:paycheck_academy/fab_bottom_app_bar.dart';
import 'package:paycheck_academy/fab_with_icons.dart';
import 'package:paycheck_academy/layout.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or press Run > Flutter Hot Reload in IntelliJ). Notice that the
        // counter didn't reset back to zero; the application is not restarted.
        primarySwatch: Colors.blueGrey,
      ),
      home: new MyHomePage(title: 'Paycheck Academy'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  String _lastSelected = 'TAB: 0';

  void _selectedTab(int index) {
    setState(() {
      _lastSelected = 'TAB: $index';
    });
  }

  void _selectedFab(int index) {
    setState(() {
      _lastSelected = 'FAB: $index';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        //Can add leading icon/function if needed
        leading: Builder(
          builder: (BuildContext context) {
            return IconButton(
              icon: Icon(Icons.menu),
              onPressed: () {},
            );
          },
        ),
/*        Icon(
          Icons.exit_to_app,
        ),*/
        actions: <Widget>[
          PopupMenuButton(
            icon: Icon(Icons.account_box),
            tooltip: 'Account',
            itemBuilder: (context) => [
              PopupMenuItem(
                child: Text(
                  'Profile',
                  style: TextStyle(
                    color: Colors.blueGrey,
                  ),
                ),
              ),
              PopupMenuItem(
                child: Text(
                  'FAQ',
                  style: TextStyle(
                    color: Colors.blueGrey,
                  ),
                ),
              ),
              PopupMenuItem(
                child: Text(
                  'Website',
                  style: TextStyle(
                    color: Colors.blueGrey,
                  ),
                ),
              ),
              PopupMenuItem(
                child: Text(
                  'Logout',
                  style: TextStyle(
                    color: Colors.blueGrey,
                  ),
                ),
              ),
            ],
          ),
        ],
        title: Text(widget.title),
        textTheme: TextTheme(
          title: TextStyle(
            color: Colors.white,
            fontSize: 22.0,
          ),
        ),
        /*actions: <Widget>[
          IconButton(
            icon: Icon(
              Icons.account_box,
              color: Colors.white,
            ),
            onPressed: () {},
          ),
        ],*/
      ),
      body: Center(
        child: Text(
          _lastSelected,
          style: TextStyle(fontSize: 32.0),
        ),
      ),
      bottomNavigationBar: FABBottomAppBar(
        centerItemText: '',
        backgroundColor: Colors.blueGrey,
        color: Colors.white,
        selectedColor: Colors.yellowAccent,
        notchedShape: CircularNotchedRectangle(),
        onTabSelected: _selectedTab,
        items: [
          FABBottomAppBarItem(
            iconData: Icons.school,
            text: 'Academy',
          ),
          FABBottomAppBarItem(
            iconData: Icons.insert_chart,
            text: 'Reports',
          ),
          FABBottomAppBarItem(
            iconData: Icons.attach_money,
            text: 'Income',
          ),
          FABBottomAppBarItem(
            iconData: Icons.local_grocery_store,
            text: 'Expense',
          ),
        ],
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      floatingActionButton: _buildFab(
          context), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  Widget _buildFab(BuildContext context) {
    final icons = [
      Icons.attach_money,
      Icons.local_grocery_store,
    ];
    return AnchoredOverlay(
      showOverlay: true,
      overlayBuilder: (context, offset) {
        return CenterAbout(
          position: Offset(offset.dx, offset.dy - icons.length * 35.0),
          child: FabWithIcons(
            icons: icons,
            onIconTapped: _selectedFab,
          ),
        );
      },
      child: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: Icon(Icons.add),
        elevation: 2.0,
      ),
    );
  }
}

2 个答案:

答案 0 :(得分:1)

所以...我尝试了这个。似乎就是您想要的。

  class CustomAppBar extends StatefulWidget implements PreferredSizeWidget{

  final double height;

  CustomAppBar({Key key,this.height}):super(key:key);

  Size get preferredSize => Size.fromHeight(height);

  @override
  _CustomAppBarState createState() => _CustomAppBarState();
}

class _CustomAppBarState extends State<CustomAppBar> {

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Container(
          color: Colors.grey[300],
          child: Padding(
            padding: EdgeInsets.all(0),
            child: Container(
              color: Colors.red,
              padding: EdgeInsets.fromLTRB(5, 30, 5, 5),
              child: Row(children: [
                PopupMenuButton(
                  icon: Icon(Icons.view_list,color:Colors.white),
                  itemBuilder: (context) => [
                    PopupMenuItem(
                      child: Text("Is this"),
                    ),
                    PopupMenuItem(
                      child: Text("What"),
                    ),
                    PopupMenuItem(
                      child: Text("You Want?"),
                    ),
                  ],
            ),
                Expanded(
                  child: Container(
                    color: Colors.transparent,
                    child: Text("Hello",
                    style: TextStyle(
                      fontSize:20.0,
                      color:Colors.white,
                    ),),
                  ),
                ),
              ]),
            ),
          ),
        ),
      ],
    );
  }
}

并且您可以使用Class In替换AppBar()。 即:appBar: CustomAppBar(height:95.0),

This is how it look

And this is the pop up

顺便说一句。我也是扑朔迷离的...所以我的代码可能有点愚蠢

答案 1 :(得分:0)

enter image description here

 Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('PopupMenuButton (Stateless)'),
      actions: <Widget>[
        PopupMenuButton(
          onSelected: (value) {
            //print the selected option
            print(value);

            //Update the current choice.
            //However, this choice won't be updated in body section since it's a Stateless widget.
            choice = value.toString();
          },
          itemBuilder: (BuildContext context) {
            return NavLinks.values.map((link) {
              return PopupMenuItem(
                value: link,
                child: Text(displayString(link)),
              );
            }).toList();
          },
        ),
      ],
    ),
    body: Center(
      child: Text(
        //Print the current choice
        choice,
        style: TextStyle(fontSize: 30),
      ),
    ),
  );
}