簡體   English   中英

如何在 Flutter 中使用 Provider 切換明暗主題?

[英]How to use a switch to change between light and dark theme with Provider in Flutter?

我是 flutter 初學者,最近我一直在嘗試弄清楚如何使用開關在深色和淺色主題之間動態切換。 我看了幾個教程,然后嘗試自己弄清楚。 幾個小時后,我到了這一點,我沒有看到任何錯誤,並且我認為代碼正在做正確的事情。 本質上問題是開關關閉,然后重新打開,主題沒有變化。 我懷疑我在某處寫了一些錯誤的代碼,但我不確定在哪里。 這是代碼:

這是我的 main.dart 文件:

import 'package:provider/provider.dart';
import 'package:working_with_fin_apis/providers/theme_provider.dart';
import 'package:working_with_fin_apis/screens/home_page.dart';
import 'package:working_with_fin_apis/screens/settings_page.dart';

void main() {
  runApp(
    MultiProvider(providers: [
      ChangeNotifierProvider(
        create: (_) => ThemeProvider(),
      ),
    ], child: const MyApp()),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        themeMode: Provider.of<ThemeProvider>(context).themeMode,
        initialRoute: '/',
        routes: {
          '/': (context) => const HomePage(),
          '/settings': (context) => const SettingsPage(),
        });
  }
}

這是我的設置。dart,其中的開關是:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:working_with_fin_apis/providers/theme_provider.dart';

class SettingsPage extends StatelessWidget {
  const SettingsPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          'PlaceHolder',
          style: TextStyle(),
        ),
        actions: [
          IconButton(
            onPressed: () {
              Navigator.pushNamed(context, '/');
            },
            icon: const Icon(Icons.arrow_back),
          ),
        ],
      ),
      body: Center(
        child: Column(
          children: [
            Switch(
              value: true,
              onChanged: Provider.of<ThemeProvider>(context).toggleTheme(true),
            ),
          ],
        ),
      ),
    );
  }
}

最后我的 theme_provider.dart 具有實際的 ChangeNotifier:

import 'package:flutter/material.dart';

class ThemeProvider with ChangeNotifier {
  ThemeMode _theme = ThemeMode.light;

  ThemeMode get themeMode => _theme;

  dynamic toggleTheme(bool isDark) {
    _theme = isDark ? ThemeMode.dark : ThemeMode.light;
    notifyListeners();
  }
}

所以我的問題是我錯過了什么? 我認為這只是通知每個不同部分的錯誤方式,但我不確定。 我試圖找到最簡單的解決方案,但我似乎無法弄清楚,大部分代碼的靈感來自與主題無關的提供者教程,所以這可能是一些問題。 歡迎任何建議或資源,謝謝。

您必須在提供程序中聲明一個 bool 變量才能使開關正常工作

bool _isDark = false;
bool get isDark => _isDark;

並將其在 function 中的值更改為新值

void toggleTheme(bool newValue) {
_isDark = newValue;
if (_theme == ThemeMode.lightTheme) {
  _theme = ThemeMode.darkTheme;
} else {
  _theme = ThemeMode.lightTheme;
}
notifyListeners();
}

並在開關小部件中使用此 bool 變量並接收 onChanged 中的值並將其傳遞給提供者 function 並在提供者調用中為 function 設置監聽為 false

Switch(
       value: Provider.of<ThemeProvider>(context).isDark,
       onChanged:(value) => Provider.of<ThemeProvider>(context,listen: false).toggleTheme(value),
      ),

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM