Flutter ListTile 文本从浅色切换到深色时不会更改主题/颜色

问题描述 投票:0回答:1

我的屏幕中有一个带有 ListTile 的 ListView,我在 MaterialApp 中定义了两个主题,并根据 themeBloc 的状态更改 themeMode,如下所示。

 MaterialApp(

        theme: AppTheme.light,
        darkTheme: AppTheme.dark,
        themeMode: context.watch<ThemeBloc>().state,
        
      ),

但是当我切换主题时,列表图块尾随文本小部件中的颜色没有改变。

ListTile(
    leadingAndTrailingTextStyle : Theme.of(context).textTheme.labelMedium,
    title: Text(state.data.elementAt(index).stockName),
    trailing: Text("My text which should change color based on theme"),
  ),

labelMedium 有浅色和深色主题两种不同的颜色

static ThemeData light = ThemeData(
    useMaterial3: true,
    colorScheme: lightColorScheme,
    brightness: Brightness.light,
    fontFamily: GoogleFonts.montserrat().fontFamily,
    textTheme: TextTheme(
        labelMedium: TextStyle(
          color: lightColorScheme.onPrimaryContainer,
          fontSize: 16,
          fontWeight: FontWeight.w500,
        ),
        ),
  );
  static ThemeData dark = ThemeData(
    useMaterial3: true,
    colorScheme: darkColorScheme,
    brightness: Brightness.dark,
    fontFamily: GoogleFonts.montserrat().fontFamily,
    textTheme: TextTheme(
        labelMedium: TextStyle(
          color: darkColorScheme.onPrimaryContainer,
          fontSize: 16,
          fontWeight: FontWeight.w500,
        ),
        ),
  );

我在应用程序栏中有一个开关,可以将主题从浅色切换到深色,这会在 ThemeBloc 中添加一个事件。 如果我不向尾随小部件提供任何 textStyle,列表图块的颜色会从黑色变为白色,但是当我提供我的样式时,它不起作用。

还有一件事,如果我切换到深色主题,颜色不会改变,但是当我转到另一个屏幕并返回到此屏幕时,颜色会改变。

我尝试为文本小部件提供相同的样式,但它也不起作用。

编辑:检查此示例https://zapp.run/edit/flutter-zr3806pdr390?entry=lib/main.dart&file=lib/main.dart

第二个屏幕无法工作,但第三个屏幕可以工作。

flutter listview bloc listtile
1个回答
0
投票

我遇到了同样的问题,所以我尝试了两种方法,但不确定哪一种有效。

我不知道你用来更改主题的逻辑,但我是这样做的:

 class AppWidget extends StatelessWidget {
  AppWidget({super.key});

  final themeProvider = ThemeProvider.getInstance();

  @override
  Widget build(BuildContext context) {
    final appRouter = router();
    //themeProvider.loadTheme();
    return ListenableBuilder(
      builder: (context, child) {
        return MaterialApp.router(
          title: 'Chess versus',
          localizationsDelegates: AppLocalizations.localizationsDelegates,
          supportedLocales: AppLocalizations.supportedLocales,
          localeResolutionCallback: (locale, supportedLocales) {
            if (locale == null) return const Locale('en');

            for (var supportedLocale in supportedLocales) {
              if (supportedLocale.languageCode == locale.languageCode) {
                return supportedLocale;
              }
            }
            return const Locale('en');
          },
          theme: lightTheme,
          darkTheme: darkTheme,
          themeMode: themeProvider.themeMode,
          routerConfig: appRouter,
        );
      },
      listenable: themeProvider,
    );
  }
}

我的主题切换状态管理器类:

忽略变量 themeService

    class ThemeProvider extends ChangeNotifier {
       final themeService = ThemeService();
       static ThemeProvider? _instance;

       ThemeProvider._();

       ThemeState state = LightThemeState();

       ThemeMode get themeMode => state.themeMode;

       switchTheme() {
         if (state is LightThemeState) {
          state = DarkThemeState();
         } else if (state is DarkThemeState) {
          state = LightThemeState();
       }
        themeService.saveLocalTheme(state.themeMode);
        notifyListeners();
      }
    }
    sealed class ThemeState {
     late final ThemeMode themeMode;
   }

   class LightThemeState extends ThemeState {
     @override
     final ThemeMode themeMode = ThemeMode.light;
   }

   class DarkThemeState extends ThemeState {
     @override
     final ThemeMode themeMode = ThemeMode.dark;
   }

1 - 我正在使用 ListView.builder 并将其切换为常规 ListView。它们有一个区别,涉及显示和构建包含许多项目的列表,这可能与此颜色变化错误有关。就我而言,当我滚动页面查看隐藏的 ListTile 项目时,它们没有出现错误。此外,滚动期间消失的错误已修复,并在重新出现时显示正确的颜色。

                           ListView(
                            children: state.tournaments.map((tournament) {
                              return Align(
                                alignment: Alignment.center,
                                child: Container(
                                  margin: EdgeInsets.symmetric(
                                      vertical: 8,
                                      horizontal: Dimens.of(context)
                                          .paddingScreenHorizontal),
                                  child: ListTile(
                                      horizontalTitleGap: Dimens.of(context)
                                          .paddingScreenHorizontal,
                                      minVerticalPadding: Dimens.of(context)
                                          .paddingScreenVertical,
                                      tileColor: Theme.of(context)
                                          .colorScheme
                                          .secondary,
                                      title: Text(
                                        tournament.getName,
                                        style: Theme.of(context)
                                            .textTheme
                                            .titleMedium,
                                      ),
                                      subtitle: Column(
                                          crossAxisAlignment:
                                              CrossAxisAlignment.start,
                                          children: [
                                            Text(
                                              tournament.getDescription ??
                                                  AppLocalizations.of(context)!
                                                      .tournamentNullDescription,
                                            ),
                                            Text(
                                              tournament.getTypeName.toString(),
                                            ),
                                            Text(
                                              DateFormat('dd/MM/yyyy').format(
                                                  tournament.getStartedAt),
                                            )
                                          ])),
                                ),
                              );
                            }).toList(),
                          ),

2 - 我在配置主题的文件中设置了 ListTile 的默认主题。这样,我就不需要用属性来扰乱小部件,从而保持代码简洁。这里很乱,但在项目中,它被分成单独的文件(笑)。

ThemeData get lightTheme => ThemeHelper().lightThemeData;

ThemeData get darkTheme => ThemeHelper().darkThemeData;

    class ThemeHelper {
      final Map<String, ColorScheme> _supportedColors = {
        'light': AppColors.lightCodeScheme,
        'dark': AppColors.darkCodeScheme,
      };
    
      ThemeData get lightThemeData => _getTheme('light');
      ThemeData get darkThemeData => _getTheme('dark');
    
      ThemeData _getTheme(String theme) {
        ColorScheme colorScheme =
            _supportedColors[theme] ?? AppColors.lightCodeScheme;
        return ThemeData(
          iconTheme: iconTheme(colorScheme),
          dialogTheme: dialogTheme(colorScheme),
          colorScheme: _supportedColors[theme],
          textTheme: TextThemes.textTheme(colorScheme),
          appBarTheme: appBarTheme(colorScheme),
          listTileTheme: listTileTheme(colorScheme),
          switchTheme: switchTheme(colorScheme),
          inputDecorationTheme: inputDecorationTheme(colorScheme),
        );
      }
    }


class AppColors {
  static const Color darkBlueGray = Color(0xFF2C3E50);
  static const Color blueGray = Color(0xFF375A7F);
  static const Color drakGray = Color(0xFF222222);
  static const Color gray = Color(0xFF3A3A3A);
  static const Color lightGray200 = Color(0xFF75818C);
  static const Color lightGray100 = Color(0xFF7F8C8D);
  static const Color lightGray = Color(0xFFB9C4C4);

  static const Color lightBlue = Color(0XFFD7E3FF);
  static const Color blue = Color(0XFF055AB2);
  static const Color white = Color(0XFFFFFFFF);
  static const Color red = Color(0XFFBA1A1A);
  static const Color purple = Color(0XFF810081);
  static const Color pink = Color(0XFFFDAFF2);
  static const Color lightRedPink = Color(0XFFFFB4AB);

  static const Color redOrange = Color(0XFFC44133);
  static const Color lightPurple = Color(0XFFEBDCFF);

  // Esquema de cores claro
  static const lightCodeScheme = ColorScheme.light(
    brightness: Brightness.light,
    primary: darkBlueGray,
    onPrimary: white,
    //surface: lightGray,
    secondary: lightGray,
    error: white,
    onError: red,
  );

  // Esquema de cores escuro
  static const darkCodeScheme = ColorScheme.dark(
    brightness: Brightness.dark,
    surface: drakGray,
    primary: blueGray,
    onPrimary: white,
    secondary: gray,
    error: redOrange,
    onError: white,
  );
}

ListTileThemeData listTileTheme(ColorScheme colorScheme) => ListTileThemeData(
      tileColor: colorScheme.secondary,
      textColor: colorScheme.onPrimary,
      iconColor: colorScheme.onPrimary,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
    );
© www.soinside.com 2019 - 2024. All rights reserved.