0

我是新手,在尝试在 Appbar 上合并一个更改整个应用程序主题的按钮时遇到问题。

这是main.dart文件代码。

import 'package:flutter/material.dart';
import 'package:qrpay_app/routes/Routes.dart';
import 'module/splash/splash_view.dart';
import 'module/buy/buy_list_view.dart';
import 'module/sell/sell_list_view.dart';
import 'module/shop/shop_list_view.dart';
import 'module/account/account_list_view.dart';
import 'module/contact/contact_list_view.dart';
import 'module/help/help_list_view.dart';
import 'module/receipts/receipts_list_view.dart';
import 'module/about us/about_us_view.dart';
import 'package:qrpay_app/Themes/appThemes.dart';

import 'module/qr/qr_view.dart';

void main() {
  runApp(new MaterialApp(
    title: 'QRPAY Touch-Free',
    theme: new ThemeData(primarySwatch: Colors.red),
    home: SplashPage(),
    routes: {
      Routes.splash: (context) => SplashPage(),
      Routes.buy: (context) => BuyPage(),
      Routes.sell: (context) => SellPage(),
      Routes.shop: (context) => ShopPage(),
      Routes.qr: (context) => QRPage(),
      Routes.account: (context) => AccountPage(),
      Routes.contact: (context) => ContactPage(),
      Routes.help: (context) => HelpPage(),
      Routes.receipts: (context) => ReceiptsPage(),
      Routes.about_us: (context) => AboutUsPage(),
    },
  ));
}

这是appThemes.dart代码:

import 'package:flutter/material.dart';

class AppThemes {
  // Simple constructor
  AppThemes._();

  static final ThemeData highContrast = ThemeData(
    primarySwatch: Colors.black,
    primaryTextTheme: TextTheme(
      headline6: TextStyle(color: Colors.white),
    ),
    scaffoldBackgroundColor: Colors.white,
    appBarTheme: AppBarTheme(
      color: Colors.black,
      iconTheme: IconThemeData(
        color: Colors.white,
      ),
      elevation: 30.0,
    ),
  );

  static final ThemeData normalContrast = ThemeData(
    scaffoldBackgroundColor: Colors.white,
    appBarTheme: AppBarTheme(
      color: Colors.red,
      iconTheme: IconThemeData(
        color: Colors.white,
      ),
    ),
  );
}

我已将家路由到splash_view.dart。这是appThemes.dart代码:

import 'package:flutter/material.dart';
import 'package:qrpay_app/widget/drawer.dart';
import 'package:qrpay_app/Themes/appThemes.dart';

class SplashPage extends StatefulWidget {
  static const String routeName = '/splash';
  @override
  _SplashPageState createState() => _SplashPageState();
}

class _SplashPageState extends State<SplashPage> {
  void changeContrast() {
    print("High contrast button clicked\nChanging app contrast\n");
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("QRPAY Touch-Free"),
        elevation: 30.0,
        actions: <Widget>[
          ElevatedButton(
              onPressed: () {
                changeContrast();
              },
              child: Text('High Contrast')),
        ],
      ),
      drawer: AppDrawer(),
      body: new Center(
        child: new Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Container(
              child: new Image.asset(
                'res/images/qplogo.png',
                width: MediaQuery.of(context).size.width * .9,
                fit: BoxFit.cover,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

我添加了一个提升按钮,需要更改整个应用程序的主题。请帮助根据我的飞镖文件映射功能。

另外,我对如何添加状态更改感到困惑

我尝试与“提供者”一起锻炼,但我感到困惑。

请有人帮助我。另外,如果您需要其他任何东西来更好地理解我的问题,请告诉我。

感谢大家抽出时间帮助我。

谢谢你。

4

3 回答 3

0

最简单的方法是使用Provider。

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(
    MultiProvider(
      providers: [
      // Used MultiProvider incase you have other providers
        ChangeNotifierProvider<ThemeDataProvider>(
          create: (_) => ThemeDataProvider(),
        ),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    ThemeDataProvider themeDataProvider = Provider.of(context);

    // Pull the theme data from the provider and make a few modification
    // The modifications are for illustration only.  Not required.
    final ThemeData currentTheme = themeDataProvider.themeData.copyWith(
      scaffoldBackgroundColor: themeDataProvider.isDarkTheme ? Colors.yellow[700] : Colors.yellow[300],
      appBarTheme: themeDataProvider.themeData.appBarTheme,
      cardTheme: themeDataProvider.themeData.cardTheme,
    );
    return MaterialApp(
      color: Colors.yellow[100],
      title: 'MyApp',
      theme: currentTheme, //set your theme
      initialRoute: setupRoute,
      onGenerateRoute: Router.generateRoute,
    );
  }
}


class ThemeDataProvider with ChangeNotifier {
  Future<SharedPreferences> _prefs = SharedPreferences.getInstance();

  SharedPreferences prefs;
  bool isInitialized;
  bool _useDarkTheme;
  double _appMargin;
  int _animationDuration = 200;
  ThemeData _themeData;

  ThemeDataProvider() {
    isInitialized = false;
    _initialize();
  }

  void _initialize() async {
    prefs = await _prefs;
    await _loadPrefs();
    _themeData = _buildThemeData();
    _appMargin = 0.0;
    isInitialized = true;
  }

  ThemeData get themeData => _themeData;

  bool get isDarkTheme => _useDarkTheme ?? true;
  double get appMargin => _appMargin;
  int get animDuration => _animationDuration;

  ///
  /// Set the application working margin.
  ///
  void setAppMargin(double appMargin) {
    _appMargin = appMargin;
  }

  void toggleTheme() {
    _useDarkTheme = !_useDarkTheme;
    _savePrefs();
    _themeData = _buildThemeData();
    notifyListeners();
  }

  Future _loadPrefs() async {
    prefs = await _prefs;
    _useDarkTheme = prefs.getBool("useDarkMode") ?? true;
    _themeData = _buildThemeData();
    notifyListeners();
  }

  void _savePrefs() async {
    prefs = await _prefs;
    prefs.setBool("useDarkMode", _useDarkTheme);
  }

// Build your theme data here
      ThemeData _buildThemeData() {
        return ThemeData(
          primarySwatch: isDarkTheme
              ? MaterialColor(4280361249, {
                  50: Color(0xfff2f2f2),
    ...

在您喜欢的任何地方添加开关,然后单击调用 toggleTheme 方法。

这不是功能代码。这是我的生产代码的编辑版本。

于 2020-11-26T18:33:28.430 回答
0

您可以在此处阅读有关 Flutter Stream 的文章:https ://medium.com/@ayushpguptaapg/using-streams-in-flutter-62fed41662e4

添加一个布尔值来跟踪当前主题

bool isHighContrast = false;

然后,当您的开关打开时,只需调用:

// switch is on, toggle isHighContrast. isHighContrast now equals to true
controller.add(isHighContrast);

然后监听更改以更新整个 UI:

controller.stream.listen({
  setState({
    theme = AppTheme.highContrast;
  });
})
于 2020-11-26T18:07:51.403 回答
0

我使用Flutter_riverpod包中的 StateProvider 来实现这一点。

// Add the global provider
final appThemeProvider = StateProvider<ThemeData>((ref) {
  return App.getDefaultThemeData();
});

class App extends ConsumerWidget {
//                ^^^^^^^^^^^^^^
  @override
  Widget build(BuildContext context, WidgetRef ref) {
//                                   ^^^^^^^^^^^^^
    final currentTheme = ref.watch(appThemeProvider).state;

    return MaterialApp(
      color: Colors.yellow[100],
      title: 'MyApp',
      theme: currentTheme, //set your theme
      initialRoute: setupRoute,
      onGenerateRoute: Router.generateRoute,
    );

    // this is default theme
    static ThemeData getDefaultThemeData() {
      return ThemeData(
        primarySwatch: MaterialColor(0xFF00FF00, mappingColor),
        backgroundColor: MaterialColor(0xFFFFFEFA, mappingColor),
      );
    }

    // use this method to changeTheme
    void _changeTheme({required WidgetRef ref, required ThemeData themeData}) {
      Future.delayed(const Duration(milliseconds: 10), () {
        ref.read(appThemeProvider).state = themeData;
      }
    }
} 
于 2021-08-23T11:53:11.743 回答