Flutter壁纸色彩提取插件palette_from_wallpaper的使用

Flutter壁纸色彩提取插件palette_from_wallpaper的使用

插件说明

这是一个用于从Android设备墙纸中提取调色板的Flutter插件。它利用了原生的android.app.WallpaperManager.getWallpaperColorsandroid.app.WallpaperManager.OnColorsChangedListener API。

该功能通过PaletteFromWallpaper.getPalette方法暴露出来,并且有一个流(Stream)来接收下一次的PlatformPalette更新,可以通过PaletteFromWallpaper.paletteUpdates字段访问。

此外,该功能还通过一个更符合Flutter风格的API通过runPlatformThemedApp函数暴露出来。当调用runPlatformThemedApp而不是runApp时,会在树的根部插入一个InheritedPalette,并订阅paletteUpdates流,以便始终通过BuildContext.dependOnInheritedWidgetOfExactType将新的调色板传播到树中,确保应用程序始终使用用户墙纸的最新颜色。

示例

以下是一个完整的示例,展示了如何使用palette_from_wallpaper插件。

示例代码

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:palette_from_wallpaper/palette_from_wallpaper.dart';

void main() {
  runPlatformThemedApp(
    MyApp(),
    onError: (e) => PlatformPalette.errorHandler(primaryColor: Colors.red),
    initialOrFallback: () =>
        PlatformPalette.fallback(primaryColor: Colors.blue),
    startEagerly: true,
  );
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  StreamSubscription? subscription;
  final scaffold = GlobalKey<ScaffoldState>();

  void dispose() {
    super.dispose();
    subscription?.cancel();
  }

  void _onPlatformUpdate(PlatformPalette palette) {
    if (!mounted) {
      return;
    }
    scaffold.currentState!
        .showSnackBar(SnackBar(content: Text('Updated theme!')));
  }

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  // 平台消息是异步的,所以我们初始化在一个异步方法中。
  void initPlatformState() {
    try {
      subscription =
          PaletteFromWallpaper.paletteUpdates.listen(_onPlatformUpdate);
    } on Object {}
  }

  Widget square(Color? color) => Expanded(
        child: AspectRatio(
          aspectRatio: 1,
          child: Container(
            constraints: BoxConstraints.expand(),
            color: color,
            child: color == null ? Text('Unavailable') : null,
          ),
        ),
      );

  Widget palette(BuildContext context) => Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Row(
            children: [
              square(context.palette.primaryColor),
              square(context.palette.secondaryColor),
              square(context.palette.tertiaryColor),
            ],
            mainAxisSize: MainAxisSize.max,
          ),
          if (context.palette.colorHints != null) ...[
            Text('HINT_SUPPORTS_DARK_TEXT: '
                '${context.palette.colorHints! & PlatformPalette.HINT_SUPPORTS_DARK_TEXT}'),
            Text('HINT_SUPPORTS_DARK_THEME: '
                '${context.palette.colorHints! & PlatformPalette.HINT_SUPPORTS_DARK_THEME}'),
          ] else
            Text('No hints available'),
          Text('PaletteSource: ${context.palette.source}'),
        ],
      );

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        key: scaffold,
        appBar: AppBar(
          title: const Text('PaletteFromWallpaper Example'),
          backgroundColor: context.palette.primaryColor,
        ),
        body: Center(
          child: palette(context),
        ),
      ),
    );
  }
}

代码解析

  1. 导入必要的库

    import 'package:flutter/material.dart';
    import 'dart:async';
    import 'package:palette_from_wallpaper/palette_from_wallpaper.dart';
    
  2. 主函数

    void main() {
      runPlatformThemedApp(
        MyApp(),
        onError: (e) => PlatformPalette.errorHandler(primaryColor: Colors.red),
        initialOrFallback: () =>
            PlatformPalette.fallback(primaryColor: Colors.blue),
        startEagerly: true,
      );
    }
    
  3. 定义MyApp

    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => _MyAppState();
    }
    
  4. 定义_MyAppState

    class _MyAppState extends State<MyApp> {
      StreamSubscription? subscription;
      final scaffold = GlobalKey<ScaffoldState>();
    
      void dispose() {
        super.dispose();
        subscription?.cancel();
      }
    
      void _onPlatformUpdate(PlatformPalette palette) {
        if (!mounted) {
          return;
        }
        scaffold.currentState!
            .showSnackBar(SnackBar(content: Text('Updated theme!')));
      }
    
      @override
      void initState() {
        super.initState();
        initPlatformState();
      }
    
      // 初始化平台状态
      void initPlatformState() {
        try {
          subscription =
              PaletteFromWallpaper.paletteUpdates.listen(_onPlatformUpdate);
        } on Object {}
      }
    
      Widget square(Color? color) => Expanded(
            child: AspectRatio(
              aspectRatio: 1,
              child: Container(
                constraints: BoxConstraints.expand(),
                color: color,
                child: color == null ? Text('Unavailable') : null,
              ),
            ),
          );
    
      Widget palette(BuildContext context) => Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Row(
                children: [
                  square(context.palette.primaryColor),
                  square(context.palette.secondaryColor),
                  square(context.palette.tertiaryColor),
                ],
                mainAxisSize: MainAxisSize.max,
              ),
              if (context.palette.colorHints != null) ...[
                Text('HINT_SUPPORTS_DARK_TEXT: '
                    '${context.palette.colorHints! & PlatformPalette.HINT_SUPPORTS_DARK_TEXT}'),
                Text('HINT_SUPPORTS_DARK_THEME: '
                    '${context.palette.colorHints! & PlatformPalette.HINT_SUPPORTS_DARK_THEME}'),
              ] else
                Text('No hints available'),
              Text('PaletteSource: ${context.palette.source}'),
            ],
          );
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            key: scaffold,
            appBar: AppBar(
              title: const Text('PaletteFromWallpaper Example'),
              backgroundColor: context.palette.primaryColor,
            ),
            body: Center(
              child: palette(context),
            ),
          ),
        );
      }
    }
    

更多关于Flutter壁纸色彩提取插件palette_from_wallpaper的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter壁纸色彩提取插件palette_from_wallpaper的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


palette_from_wallpaper 是一个用于从壁纸中提取主色调的 Flutter 插件。它可以帮助你从设备的壁纸中提取颜色,并将其应用到你的应用中,以实现与壁纸风格一致的设计。

安装

首先,你需要在 pubspec.yaml 文件中添加 palette_from_wallpaper 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  palette_from_wallpaper: ^1.0.0 # 请使用最新版本

然后运行 flutter pub get 来安装插件。

使用

  1. 导入插件

    在你的 Dart 文件中导入 palette_from_wallpaper 插件:

    import 'package:palette_from_wallpaper/palette_from_wallpaper.dart';
    
  2. 获取壁纸颜色

    使用 PaletteFromWallpaper.getColors() 方法从壁纸中提取颜色。这个方法会返回一个 PaletteColors 对象,其中包含了从壁纸中提取的颜色。

    Future<void> getWallpaperColors() async {
      try {
        PaletteColors colors = await PaletteFromWallpaper.getColors();
        print('Dominant Color: ${colors.dominantColor}');
        print('Vibrant Color: ${colors.vibrantColor}');
        print('Light Vibrant Color: ${colors.lightVibrantColor}');
        print('Dark Vibrant Color: ${colors.darkVibrantColor}');
        print('Muted Color: ${colors.mutedColor}');
        print('Light Muted Color: ${colors.lightMutedColor}');
        print('Dark Muted Color: ${colors.darkMutedColor}');
      } catch (e) {
        print('Failed to get wallpaper colors: $e');
      }
    }
    
  3. 应用颜色

    你可以将提取到的颜色应用到你的 UI 中。例如,将 dominantColor 作为背景色:

    class MyApp extends StatelessWidget {
      final Color dominantColor;
    
      MyApp({required this.dominantColor});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            backgroundColor: dominantColor,
            body: Center(
              child: Text('Hello, World!', style: TextStyle(color: Colors.white)),
            ),
          ),
        );
      }
    }
    
  4. 完整示例

    以下是一个完整的示例,展示了如何从壁纸中提取颜色并应用到 UI 中:

    import 'package:flutter/material.dart';
    import 'package:palette_from_wallpaper/palette_from_wallpaper.dart';
    
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      PaletteColors colors = await PaletteFromWallpaper.getColors();
      runApp(MyApp(dominantColor: colors.dominantColor));
    }
    
    class MyApp extends StatelessWidget {
      final Color dominantColor;
    
      MyApp({required this.dominantColor});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            backgroundColor: dominantColor,
            body: Center(
              child: Text('Hello, World!', style: TextStyle(color: Colors.white)),
            ),
          ),
        );
      }
    }
回到顶部