如何在Flutter中设置AppBar操作按钮的颜色

时间:2019-09-09 19:29:42

标签: flutter

我正在尝试通过主题设置AppBar操作图标的颜色,但是由于某种原因,它不起作用。这是我的最小代码示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
        iconTheme: IconThemeData(color: Colors.purple),
        primaryIconTheme: IconThemeData(color: Colors.red),
        accentIconTheme: IconThemeData(color: Colors.amber)
      ),
    home: Scaffold(
      appBar: AppBar(
        iconTheme: IconThemeData(color: Colors.green),
        actionsIconTheme: IconThemeData(color: Colors.yellow),
        actions: [
          IconButton(icon: Icon(Icons.add))
        ]
      )
    ));
  }
}
  • iconTheme颜色值中的任何一个都不起作用。
  • MaterialApp.iconThemeAppBar.iconThemeAppBar.actionsIconTheme中设置不透明度实际上会生效
  • 明确设置Icon.color确实可以,但是我认为我不需要这样做吗?

如何使IconButton尊重我的主题?

谢谢 托马斯

编辑:通过直接使用Icon而不是IconButton,我实际上可以使图标尊重我的主题,但是如何使它可点击?根据{{​​3}},IconButtonAppBar.actions中最常用的窗口小部件。那不对吗?

3 个答案:

答案 0 :(得分:1)

使App Bar Widget成为通用类

enum ButtontType {
  back,
  menu
}

class topBarWidget {

//region TopBar
  static AppBar createTopBar(
  {
    String title,
    double elevation = 1.5,
    TextStyle titleStyle,
    Widget titleWidget,
    List<ButtontType> leftIcons = const [],
    List<ButtontType> rightIcons = const [],
    ButtonTapCallback action,
    EdgeInsetsDirectional padding = const EdgeInsetsDirectional.only(start: 10, end: 10.0),
    Color backgroundColor,
    Color iconColor,
    bool centerTitle = true}) {
var titleText = titleWidget;

if (titleText == null) {
  titleText = Text(
    title,
    softWrap: true,
    style: txtStyle,
    ),
  );
}

var leftmenuWidget;
List<Widget> rightRowChildern = [];

final size = 18.0;
final tapAreasize = 32.0;

if (leftIcons.length > 0) {
  List<Widget> mainRowChildern = [];
  mainRowChildern.add(Padding(padding: EdgeInsets.only(left: 10.0)));
  for (int i = 0; i < leftIcons.length; i++) {

    final menuIconImage = Image.asset(_getImageName(type: leftIcons[i]),color: Colors.black,);
    final menuIconImageSizeBox = SizedBox(child: menuIconImage, width: size, height: size,);
    // ignore: unnecessary_statements
    final menuIconAction = Container(color: Colors.transparent,child: InkWell(onTap: () {(action != null) ? action(leftIcons[i]) : null;},child: ClipOval(child: Container(alignment: Alignment.center,width: tapAreasize,height: tapAreasize,color: Colors.transparent,child:menuIconImageSizeBox,),),),);
    //final menuIconAction = InkWell(child: menuIconImageSizeBox, onTap: () => (action != null) ? action(leftIcons[i]) : null, );
    mainRowChildern.add(menuIconAction);
  }

  leftmenuWidget = Row(children: mainRowChildern, mainAxisAlignment: MainAxisAlignment.start,);
}

if (rightIcons.length > 0) {
  for (int i = 0; i < rightIcons.length; i++) {

    Widget menuIconImage = Image.asset(_getImageName(type: rightIcons[i]),color: Colors.black,);

    if(_getImageName(type: rightIcons[i]) == _getImageName(type: ButtontType.notificationUnread)){
      menuIconImage = Image.asset(_getImageName(type: rightIcons[i]),);
    } else{
      menuIconImage = Image.asset(_getImageName(type: rightIcons[i]),color: Colors.yellow,);
    }

    var menuIconImageSizeBox;
    menuIconImageSizeBox = SizedBox(child: menuIconImage, width: size * 1.5, height: size * 1.5,);
    final menuIconAction = InkWell(child: menuIconImageSizeBox, onTap: () => (action != null) ? action(rightIcons[i]) : null,);
    rightRowChildern.add(menuIconAction);

    if (i != (rightIcons.length - 1)) {
      rightRowChildern.add(Padding(padding: EdgeInsets.only(right: 12.0)));
    }
  }
  rightRowChildern.add(Padding(padding: EdgeInsets.only(right: 16.0)));
  rightRowChildern = [
    Row(
      children: rightRowChildern,
    )
  ];
}

var topBar = AppBar(
  elevation: elevation,
  brightness: Brightness.light,
  backgroundColor: backgroundColor ?? Colors.white,
  leading: leftmenuWidget ?? SizedBox(),
  actions: rightRowChildern,
  title: titleText,
  centerTitle: centerTitle,
  titleSpacing: 0,
);

return topBar;
  }
  //endregion


static String _getImageName({ButtontType type}) {
    var iconName;
   if (type == ButtontType.back) {
      iconName = 'images/back.png';
    } else if (type == ButtontType.menu) {
      iconName = 'images/menu.png';
    } 
    return iconName;
  }
}

现在如何使用

的示例
// Appbar for notes page
final appBar = topBarWidget.createTopBar(
    titleStyle: txtStyle,
    title: "App Bar",
    leftIcons: [ButtontType.back],
    backgroundColor: Colors.white,
    action: (ButtontType type) {
      Navigator.of(context).pop();
    });

   var scaffold = Scaffold(
      appBar: appBar,
      body: scaffoldBuilder,
    );

希望获得帮助!

答案 1 :(得分:0)

假设您是通过尊重主题来实现的,即当应用程序栏为黑暗时希望它们为白色,反之亦然,只需在应用程序栏中使用brightness属性

例如:

AppBar(
  backgroundColor: Color.fromARGB(1023, 255, 112, 5),
  brightness: Brightness.dark,
  title: Text(
    'title',
  ),
)

或者如果您想继续使用您现在拥有的东西,您可以用墨水瓶包装图标,然后您将获得onTap来管理触摸!

答案 2 :(得分:0)

因此,显然我的问题是我没有定义 Gender Question Answer 0 1 Q1 0 1 1 Q1 0 2 0 Q1 2 3 0 Q1 0 4 0 Q1 1 的{​​{1}}属性。添加完之后,我的主题就可以正确应用了。

我知道这是必填属性,但是在构建/运行应用程序时没有出现任何错误。