You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Material3中NavigationDrawerDestination选中图标颜色修改方案

Flutter Material3修改NavigationDrawerDestination选中状态图标颜色问题及解决

各位好,这是我第一次在StackOverflow提问。我正在为项目开发CMS,遇到一个问题:使用Material3的ColorScheme时,无法修改NavigationDrawerDestination选中状态下的图标颜色。我尝试修改ColorScheme的所有参数,但没有效果,且不想通过Icon或IconThemeData的参数直接修改颜色。

示例代码

主文件代码

import 'package:cms_stackoverflow_exemple/CMS/material_custom.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Example',
      theme: MaterialCustom().themeData,
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final GlobalKey<ScaffoldState> _key = GlobalKey();
  int indexDestination = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _key,
      floatingActionButton: FloatingActionButton(onPressed: (){
        _key.currentState?.openDrawer();
      }),
      drawer: NavigationDrawer(
        selectedIndex: indexDestination,
        children: const [
          NavigationDrawerDestination(icon: Icon(Icons.verified_user), label: Text('Example')),
          NavigationDrawerDestination(icon: Icon(Icons.verified_user), label: Text('Example')),
        ],
        onDestinationSelected: (value){
          setState(() {
            indexDestination = value;
          });
        },
      ),
    );
  }
}

自定义ColorScheme代码

import 'package:flutter/material.dart';

class ColorSchemeCustomExemple {
  Color primaryColor = const Color(0xFF284664);
  Color secondaryColor = const Color(0xFF284664);

  Color tertiaryColor = const Color(0xFF62B8F4);
  Color surfaceColor = const Color(0xFF62B8F4);
  
  Color backgroundColor = const Color(0xFFFFFFFF);

  Color onTertiaryColor = const Color(0xFF9E9E9E);
  Color onSurfaceColor = const Color(0xFF9E9E9E);



  ColorScheme get colorScheme {
    Color background = Colors.white;

    return ColorScheme(
      brightness: Brightness.light,
      primary: primaryColor,
      onPrimary: Colors.white,// onPrimaryColor,
      primaryContainer: negative(color: primaryColor, iteration: 3),
      onPrimaryContainer: Colors.white, //negative(color: onPrimaryColor, iteration: 3),
      secondary: secondaryColor,
      onSecondary: Colors.white/*onSecondaryColor*/,
      secondaryContainer: negative(color: secondaryColor, iteration: 3),
      onSecondaryContainer: Colors.white/*negative(color: onSecondaryColor, iteration: 3)*/,
      tertiary: tertiaryColor,
      onTertiary: onTertiaryColor,
      tertiaryContainer: negative(color: tertiaryColor, iteration: 3),
      onTertiaryContainer: negative(color: onTertiaryColor, iteration: 3),
      error: const Color(0xFFB3261E),
      onError: const Color(0xFFFFFFFF),
      errorContainer: const Color(0xFFF9DEDC),
      onErrorContainer: const Color(0xFF410E0B),
      outline: const Color(0xFF79747E),
      background: backgroundColor,
      onBackground: negative(color: background, iteration: 5),
      surface: backgroundColor/*surfaceColor*/,
      onSurface: onSurfaceColor,
      surfaceVariant: negative(color: surfaceColor, iteration: 3),
      onSurfaceVariant: negative(color: onSurfaceColor,iteration: 3),
      inverseSurface: reverse(color: surfaceColor),
      onInverseSurface: negative(color: reverse(color: onSurfaceColor), iteration: 3),
      inversePrimary: reverse(color: primaryColor),
      shadow: const Color(0xFF000000),
      surfaceTint: backgroundColor/*positive(color: surfaceColor,iteration: 3)*/,
      outlineVariant: const Color(0xFFCAC4D0),
      scrim: const Color(0xFF000000),
    );
  }

  static Color reverse({required Color color}){
    return Color.fromRGBO(
        255 - color.red,
        255 - color.green,
        255 - color.blue,
        1
    );
  }

  static Color positive({required Color color,required int iteration}){
    Color res = color;
    double positive = 10;
    for(int i = 0;i<iteration;i++){
      res = Color.fromRGBO(
          ((res.red + positive) < 255) ? (res.red != 0) ? (res.red + positive).round() : 35 : 255,
          ((res.green + positive) < 255) ? (res.green != 0) ? (res.green + positive).round() : 35  : 255,
          ((res.blue + positive) < 255) ? (res.blue != 0) ? (res.blue + positive).round() : 35 : 255,
          1
      );
    }
    return res;
  }

  static Color negative({required Color color,required int iteration}){
    Color res = color;
    double negative = 10;
    for(int i = 0;i<iteration;i++){
      res = Color.fromRGBO(
          ((res.red - negative) > 0) ? (res.red - negative).round() : 0,
          ((res.green - negative) > 0) ? (res.green - negative).round() : 0,
          ((res.blue - negative) > 0) ? (res.blue - negative).round() : 0,
          1
      );
    }
    return res;
  }
}

自定义Material主题代码

class MaterialCustom {

  /*final Color
  primaryColor,
  secondaryColor,
  tertiaryColor,
  backgroundColor,
  surfaceColor;

  MaterialCustom({
    this.primaryColor = const Color(0xFF284664),
    this.secondaryColor = const Color(0xFF000000),
    this.tertiaryColor = const Color(0xFF62B8F4),
    this.backgroundColor = const Color(0xFFFFFFFF),
    this.surfaceColor = const Color(0xFF9E9E9E),
  });*/

  ThemeData get themeData {
    ColorScheme colorScheme = ColorSchemeCustomExemple().colorScheme;/*ColorSchemeCustom(
        primaryColor: primaryColor,
        onPrimaryColor: secondaryColor,

        secondaryColor: primaryColor,
        onSecondaryColor: secondaryColor,

        tertiaryColor: surfaceColor,
        onTertiaryColor: tertiaryColor,

        surfaceColor: surfaceColor,
        onSurfaceColor: tertiaryColor,

        backgroundColor: backgroundColor,

    ).colorScheme;*/
    
    return ThemeData(
      useMaterial3: true,
      colorScheme: colorScheme,
      
      // All is simple @Override but is not change
      inputDecorationTheme: InputDecorationThemeCustom().inputDecorationTheme,
      pageTransitionsTheme: PAgeTransitionsThemeCustom().pageTransitionsTheme,
      scrollbarTheme: ScrollbarThemeDataCustom().scrollbarTheme,
      iconTheme: IconThemeDataCustom().iconTheme,
      primaryIconTheme: IconThemeDataCustom().primaryIconTheme,
      actionIconTheme: ActionIconThemeDataCustom().actionIconTheme,
      textTheme: TextThemeCustom().textTheme,
      primaryTextTheme: TextThemeCustom().primaryTextTheme,
      appBarTheme:AppBarThemeCustom().appBarTheme,
      badgeTheme: BadgeThemeDataCustom().badgeTheme,
      bannerTheme: MaterialBannerThemeDataCustom().bannerTheme,
      bottomAppBarTheme: BottomAppBarThemeCustom().bottomAppBarTheme,
      bottomNavigationBarTheme: BottomNavigationBarThemeDataCustom().bottomNavigationBarTheme,
      bottomSheetTheme: BottomSheetThemeDataCustom().bottomSheetTheme,
      buttonBarTheme: ButtonBarThemeDataCustom().buttonBarTheme,
      buttonTheme:ButtonThemeDataCustom().buttonTheme ,
      cardTheme: CardThemeCustom().cardTheme,
      checkboxTheme: CheckboxThemeDataCustom().checkboxTheme,
      chipTheme: ChipThemeDataCustom().chipTheme,
      dataTableTheme: DataTableThemeDataCustom().dataTableTheme,
      datePickerTheme: DataPickerThemeDataCustom().datePickerTheme,
      dialogTheme: DialogThemeCustom().dialogTheme,
      dividerTheme: DividerThemeDataCustom().dividerTheme,
      drawerTheme: DrawerThemeDataCustom().drawerTheme,
      dropdownMenuTheme: DropdownMenuThemeDataCustom().dropdownMenuTheme,
      elevatedButtonTheme: ElevatedButtonThemeDataCustom().elevatedButtonTheme,
      expansionTileTheme: ExpansionTileThemeDataCustom().expansionTileTheme,
      filledButtonTheme: FilledButtonThemeDataCustom().filledButtonTheme,
      floatingActionButtonTheme: FloatingActionButtonThemeDataCustom().floatingActionButtonTheme,
      iconButtonTheme: IconButtonThemeDataCustom().iconButtonTheme,
      listTileTheme: ListTileThemeDataCustom().listTileTheme,
      menuBarTheme: MenuBarThemeDataCustom().menuBarTheme,
      menuButtonTheme: MenuButtonThemeDataCustom().menuButtonTheme,
      menuTheme: MenuThemeDataCustom().menuTheme,
      navigationBarTheme: NavigationBarThemeDataCustom().navigationBarTheme,
      navigationDrawerTheme: NavigationDrawerThemeDataCustom().navigationDrawerTheme,
      navigationRailTheme: NavigationRailThemeDataCustom().navigationRailTheme,
      outlinedButtonTheme: OutlinedButtonThemeDataCustom().outlinedButtonTheme,
      popupMenuTheme: PopupMenuThemeDataCustom().popupMenuTheme,
      progressIndicatorTheme: ProgressIndicatorThemeDataCustom().progressIndicatorTheme,
      radioTheme: RadioThemeDataCustom().radioTheme,
      searchBarTheme: SearchBarThemeDataCustom().searchBarTheme,
      searchViewTheme: SearchViewThemeDataCustom().searchViewTheme,
      segmentedButtonTheme: SegmentedButtonThemeDataCustom().segmentedButtonTheme,
      sliderTheme: SliderThemeDataCustom().sliderTheme,
      snackBarTheme: SnackBarThemeDataCustom().snackBarTheme,
      switchTheme: SwitchThemeDataCustom().switchTheme,
      tabBarTheme: TabBarThemeCustom().tabBarTheme,
      textButtonTheme: TextButtonThemeDataCustom().textButtonTheme,
      textSelectionTheme: TextSelectionThemeDataCustom().textSelectionTheme,
      timePickerTheme: TimePickerThemeDataCustom().timePickerTheme,
      toggleButtonsTheme: ToggleButtonsThemeDataCustom().toggleButtonsTheme,
      tooltipTheme: TooltipThemeDataCustom().tooltipTheme,
    );
  }
}

自定义IconTheme代码

import 'package:flutter/material.dart';

class IconThemeDataCustom {

  IconThemeData get iconTheme{
    return const IconThemeData(
      //size: ,
      //fill: ,
      //weight: ,
      //grade: ,
      //opticalSize: ,
      //color: ,
      //opacity: ,
      //shadows: ,
    );
  }

  IconThemeData get primaryIconTheme{
    return const IconThemeData(
      //size: ,
      //fill: ,
      //weight: ,
      //grade: ,
      //opticalSize: ,
      //color: ,
      //opacity: ,
      //shadows: ,
    );
  }
}

自定义NavigationDrawerTheme代码(初始)

import 'package:flutter/material.dart';

class NavigationDrawerThemeDataCustom {
  NavigationDrawerThemeData get navigationDrawerTheme {
    return const NavigationDrawerThemeData(
      // tileHeight: ,
      // backgroundColor: ,
      // elevation: ,
      // shadowColor: ,
      // surfaceTintColor: ,
      // indicatorColor: ,
      // indicatorShape: ,
      // indicatorSize: ,
      // labelTextStyle: ,
      //iconTheme: ,
    );
  }
}

问题解决方法

修改自定义的NavigationDrawerThemeData,通过MaterialStateProperty.resolveWith根据组件的状态动态设置图标颜色,代码如下:

NavigationDrawerThemeData get navigationDrawerTheme {
    return NavigationDrawerThemeData(
      // tileHeight: ,
      // backgroundColor: ,
      // elevation: ,
      // shadowColor: ,
      // surfaceTintColor: ,
      // indicatorColor: ,
      // indicatorShape: ,
      // indicatorSize: ,
      // labelTextStyle: ,
      iconTheme: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
        if (states.contains(MaterialState.selected)) {
          return IconThemeData(color: Colors.red); // 设置选中状态下的图标颜色
        }
        return IconThemeData(); // 默认图标样式
      }),
    );
  }

感谢@Md. Yeasin Sheikh的帮助。


内容的提问来源于stack exchange,提问作者Mr. Munsch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 13:09:52