Flutter日夜模式切换插件day_night_switch的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter日夜模式切换插件 day_night_switch 的使用

简介

DayNightSwitch 是一个用于Flutter的日夜间模式切换的控件。通过它可以轻松实现日间和夜间的切换效果。

示例GIF

安装

在项目的 pubspec.yaml 文件中添加依赖:

dependencies:
  day_night_switch: ^1.0.0

然后运行以下命令来获取包:

flutter pub get

使用方法

要使用该插件,只需导入包即可:

import 'package:day_night_switch/day_night_switch.dart';

示例代码

下面是一个完整的示例代码,展示了如何使用 DayNightSwitch 控件,并根据开关状态改变背景颜色、显示不同的图片等。

main.dart

import 'dart:math';
import 'package:day_night_switch/day_night_switch.dart';
import 'package:flutter/material.dart';

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

const dayColor = Color(0xFFd56352);
const nightColor = Color(0xFF1e2230);

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Day Night Switch',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

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

  @override
  MyHomePageState createState() => MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  bool val = false;
  late AnimationController _controller;
  late Size size;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      lowerBound: 0.5,
      duration: const Duration(seconds: 5),
    )..repeat();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    size = MediaQuery.of(context).size;
    return Scaffold(
      backgroundColor: val ? nightColor : dayColor,
      body: AnimatedContainer(
        color: val ? nightColor : dayColor,
        duration: const Duration(milliseconds: 300),
        child: Stack(
          children: <Widget>[
            ..._buildStars(20),
            Positioned(
              bottom: 0,
              right: 0,
              left: 0,
              height: 200,
              child: Opacity(
                opacity: val ? 0 : 1.0,
                child: Image.asset('assets/cloud.png', fit: BoxFit.cover),
              ),
            ),
            Positioned(
              bottom: 0,
              right: 0,
              height: 200,
              child: Image.asset(val ? 'assets/mountain2_night.png' : 'assets/mountain2.png', fit: BoxFit.cover),
            ),
            Positioned(
              bottom: -10,
              left: 0,
              right: 0,
              height: 140,
              child: Image.asset(val ? 'assets/mountain_night.png' : 'assets/mountain1.png', fit: BoxFit.cover),
            ),
            AnimatedBuilder(
              animation: _controller,
              builder: (context, child) {
                return Stack(
                  children: <Widget>[
                    Positioned(
                      bottom: -20,
                      right: 0,
                      left: 0,
                      child: Transform.translate(
                        offset: Offset(50 * _controller.value, 0),
                        child: Opacity(
                          opacity: val ? 0.0 : 0.8,
                          child: Image.asset('assets/cloud2.png', fit: BoxFit.cover),
                        ),
                      ),
                    ),
                    Positioned(
                      bottom: -20,
                      right: 0,
                      left: 0,
                      child: Transform.translate(
                        offset: Offset(100 * _controller.value, 0),
                        child: Opacity(
                          opacity: val ? 0.0 : 0.4,
                          child: Image.asset('assets/cloud3.png', fit: BoxFit.cover),
                        ),
                      ),
                    ),
                  ],
                );
              },
            ),
            Center(
              child: DayNightSwitch(
                value: val,
                moonImage: const AssetImage('assets/moon.png'),
                onChanged: (value) {
                  setState(() {
                    val = value;
                  });
                },
              ),
            ),
          ],
        ),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.endTop,
      floatingActionButton: Transform.translate(
        offset: const Offset(160, -360),
        child: _buildSun(),
      ),
    );
  }

  Widget _buildSun() {
    return SizedBox(
      width: double.maxFinite,
      height: double.maxFinite,
      child: AnimatedBuilder(
        animation: CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn),
        builder: (context, child) {
          return Stack(
            alignment: Alignment.center,
            children: <Widget>[
              _buildContainer(400 * _controller.value),
              _buildContainer(500 * _controller.value),
              _buildContainer(600 * _controller.value),
              SizedBox(
                width: 256,
                height: 256,
                child: val
                    ? Image.asset('assets/moon.png')
                    : const CircleAvatar(backgroundColor: Color(0xFFFDB813)),
              ),
            ],
          );
        },
      ),
    );
  }

  Widget _buildContainer(double radius) {
    return Container(
      width: radius,
      height: radius,
      decoration: BoxDecoration(
        shape: BoxShape.circle,
        color: (val ? Colors.amber[100] : Colors.orangeAccent)?.withOpacity(1 - _controller.value),
      ),
    );
  }

  List<Widget> _buildStars(int starCount) {
    List<Widget> stars = [];
    for (int i = 0; i < starCount; i++) {
      stars.add(_buildStar(top: randomX, left: randomY, val: val));
    }
    return stars;
  }

  double get randomX {
    int maxX = (size.height).toInt();
    return Random().nextInt(maxX).toDouble();
  }

  double get randomY {
    int maxY = (size.width).toInt();
    return Random().nextInt(maxY).toDouble();
  }

  Widget _buildStar({double top = 0, double left = 0, bool val = false}) {
    return Positioned(
      top: top,
      left: left,
      child: Opacity(
        opacity: val ? 1 : 0,
        child: const CircleAvatar(radius: 2, backgroundColor: Colors.white),
      ),
    );
  }
}

注意事项

  • 确保你已经将所有的图片资源(如 moon.png, sun.png, cloud.png 等)放置在正确的路径下。
  • 可以根据需要调整 dayColornightColor 来设置白天和夜晚的颜色。

通过这个示例,你可以看到如何使用 DayNightSwitch 控件来切换日夜模式,并且动态更改背景和其他UI元素的状态。


更多关于Flutter日夜模式切换插件day_night_switch的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter日夜模式切换插件day_night_switch的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter应用中使用day_night_switch插件来实现日夜模式切换的代码示例。day_night_switch插件可以帮助你轻松地在应用中实现日夜主题切换功能。

首先,确保你已经在pubspec.yaml文件中添加了day_night_switch依赖:

dependencies:
  flutter:
    sdk: flutter
  day_night_switch: ^最新版本号  # 请替换为实际的最新版本号

然后运行flutter pub get来安装依赖。

接下来,在你的Flutter应用中实现日夜模式切换。以下是一个简单的示例:

1. 初始化应用

main.dart文件中,设置MaterialApp的主题,并使用Provider来管理应用的主题状态(你可以使用其他状态管理库,如RiverpodGetX等,这里以Provider为例)。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:day_night_switch/day_night_switch.dart';

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

class ThemeNotifier with ChangeNotifier {
  bool isDarkMode = false;

  void toggleTheme() {
    isDarkMode = !isDarkMode;
    notifyListeners();
  }

  ThemeData getTheme() {
    return isDarkMode
        ? ThemeData.dark()
        : ThemeData.light();
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final themeNotifier = Provider.of<ThemeNotifier>(context);

    return MaterialApp(
      title: 'Flutter Demo',
      theme: themeNotifier.getTheme(),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Day Night Switch Demo'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              DayNightSwitch(
                onChanged: (bool value) {
                  final themeNotifier = Provider.of<ThemeNotifier>(context, listen: false);
                  themeNotifier.toggleTheme();
                },
                initialValue: themeNotifier.isDarkMode,
              ),
              SizedBox(height: 20),
              Text(
                'Current Theme: ${themeNotifier.isDarkMode ? 'Dark' : 'Light'}',
                style: TextStyle(fontSize: 20),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

2. 使用DayNightSwitch组件

在上面的代码中,DayNightSwitch组件用于切换日夜模式。当用户点击开关时,onChanged回调会被触发,然后调用themeNotifier.toggleTheme()方法来切换主题,并通知监听器(即MaterialApp)更新主题。

3. 自定义主题

你可以根据需要自定义ThemeData。例如,如果你想为暗模式和亮模式设置不同的颜色,可以修改getTheme方法:

ThemeData getTheme() {
  return isDarkMode
      ? ThemeData(
          brightness: Brightness.dark,
          primarySwatch: Colors.blueGrey,
          // 其他自定义设置
        )
      : ThemeData(
          brightness: Brightness.light,
          primarySwatch: Colors.blue,
          // 其他自定义设置
        );
}

这样,你就完成了一个简单的Flutter应用,其中包含了使用day_night_switch插件实现的日夜模式切换功能。你可以根据需要进一步扩展和自定义这个主题切换逻辑。

回到顶部