dynamic_app_icon_plus 1.0.0 copy "dynamic_app_icon_plus: ^1.0.0" to clipboard
dynamic_app_icon_plus: ^1.0.0 copied to clipboard

PlatformAndroid

A Flutter plugin for dynamically changing app icons on Android at runtime with simple YAML configuration. Android only.

example/lib/main.dart

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Initialize the plugin
  try {
    await DynamicAppIconPlus.initialize('example_config.yaml');
    print('Plugin initialized successfully');
  } catch (e) {
    print('Failed to initialize plugin: $e');
  }
  
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Dynamic App Icons Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Dynamic App Icons Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  String? currentIcon;
  bool isLoading = false;

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

  Future<void> _loadCurrentIcon() async {
    try {
      final icon = await DynamicAppIconPlus.getCurrentIcon();
      setState(() {
        currentIcon = icon;
      });
    } catch (e) {
      print('Failed to load current icon: $e');
    }
  }

  Future<void> _changeIcon(String iconIdentifier) async {
    setState(() {
      isLoading = true;
    });

    try {
      final success = await DynamicAppIconPlus.changeIcon(iconIdentifier);
      if (success) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Icon changed to $iconIdentifier successfully!'),
            backgroundColor: Colors.green,
          ),
        );
        await _loadCurrentIcon();
      } else {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Failed to change icon'),
            backgroundColor: Colors.red,
          ),
        );
      }
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('Error: $e'),
          backgroundColor: Colors.red,
        ),
      );
    } finally {
      setState(() {
        isLoading = false;
      });
    }
  }

  Future<void> _resetToDefault() async {
    setState(() {
      isLoading = true;
    });

    try {
      final success = await DynamicAppIconPlus.resetToDefault();
      if (success) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Icon reset to default successfully!'),
            backgroundColor: Colors.green,
          ),
        );
        await _loadCurrentIcon();
      } else {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Failed to reset icon'),
            backgroundColor: Colors.red,
          ),
        );
      }
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('Error: $e'),
          backgroundColor: Colors.red,
        ),
      );
    } finally {
      setState(() {
        isLoading = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Current Icon:',
                      style: Theme.of(context).textTheme.titleLarge,
                    ),
                    SizedBox(height: 8),
                    Text(
                      currentIcon ?? 'Default',
                      style: Theme.of(context).textTheme.bodyLarge?.copyWith(
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ],
                ),
              ),
            ),
            SizedBox(height: 16),
            Text(
              'Available Icons:',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            SizedBox(height: 8),
            ListView.builder(
              shrinkWrap: true,
              itemCount: DynamicAppIconPlus.availableIconDetails.length,
              itemBuilder: (context, index) {
                final icon = DynamicAppIconPlus.availableIconDetails[index];
                final isCurrent = currentIcon == icon['identifier'];
                return Card(
                  child: InkWell(
                    onTap: (){
                      DynamicAppIconPlus.changeIcon(icon['identifier']!);
                    },
                    child: ListTile(

                      leading: Image.asset(icon['path']!, width: 48, height: 48),
                      title: Text(icon['label']!),
                      subtitle: Text(icon['description']!),
                      // trailing: isCurrent ? Icon(Icons.check, color: Colors.green) : null,

                      trailing: Icon(Icons.check_circle, color: isCurrent?Colors.green:Colors.grey,)
                    ),
                  ),
                );
              },
            ),
            // Expanded(
            //   child: ListView(
            //     children: [
            //       ...DynamicAppIconPlus.availableIcons.map((iconId) {
            //         final isCurrent = currentIcon == iconId;
            //         return Card(
            //           margin: EdgeInsets.only(bottom: 8),
            //           child: ListTile(
            //             title: Text(iconId),
            //             subtitle: Text(isCurrent ? 'Currently Active' : 'Tap to activate'),
            //             trailing: isCurrent ? Icon(Icons.check, color: Colors.green) : null,
            //             onTap: isLoading ? null : () => _changeIcon(iconId),
            //           ),
            //         );
            //       }).toList(),
            //     ],
            //   ),
            // ),
            SizedBox(height: 16),
            ElevatedButton(
              onPressed: isLoading ? null : _resetToDefault,
              child: Text('Reset to Default'),
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.orange,
                padding: EdgeInsets.symmetric(vertical: 16),
              ),
            ),
            if (isLoading)
              Padding(
                padding: const EdgeInsets.all(16.0),
                child: Center(
                  child: CircularProgressIndicator(),
                ),
              ),
          ],
        ),
      ),
    );
  }
}
4
likes
140
points
30
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin for dynamically changing app icons on Android at runtime with simple YAML configuration. Android only.

Repository (GitHub)
View/report issues

Topics

#android #icons #dynamic #runtime #configuration

Documentation

API reference

License

MIT (license)

Dependencies

flutter, path, yaml

More

Packages that depend on dynamic_app_icon_plus

Packages that implement dynamic_app_icon_plus