-
-
Save aednlaxer/1cc2c70a2e8d5b08881b31082a624415 to your computer and use it in GitHub Desktop.
Flutter app - get Material You colors via platform channel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:materialyou_demo/platform_colors.dart'; | |
void main() { | |
runApp(const MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
const MyApp({Key? key}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return FutureBuilder( | |
future: getMaterialYouColor(), | |
builder: (context, AsyncSnapshot<MaterialYouPalette?> snapshot) { | |
final primarySwatch = snapshot.data?.accent1 ?? Colors.blue; | |
final accent2Swatch = snapshot.data?.accent2 ?? Colors.blue; | |
final accent3Swatch = snapshot.data?.accent3 ?? Colors.blue; | |
return MaterialApp( | |
title: 'Flutter Demo', | |
theme: ThemeData( | |
primarySwatch: primarySwatch, | |
checkboxTheme: CheckboxThemeData( | |
fillColor: MaterialStateProperty.resolveWith((states) => accent2Swatch), | |
), | |
elevatedButtonTheme: ElevatedButtonThemeData( | |
style: ButtonStyle( | |
backgroundColor: MaterialStateProperty.resolveWith((states) => accent3Swatch), | |
), | |
), | |
floatingActionButtonTheme: FloatingActionButtonThemeData( | |
backgroundColor: accent3Swatch.shade300, | |
), | |
bottomNavigationBarTheme: BottomNavigationBarThemeData( | |
backgroundColor: accent2Swatch.shade100, | |
selectedIconTheme: IconThemeData( | |
color: accent2Swatch.shade900, | |
), | |
unselectedIconTheme: IconThemeData( | |
color: accent2Swatch.shade300, | |
), | |
selectedItemColor: Colors.black, | |
unselectedItemColor: Colors.black, | |
), | |
), | |
home: const _HomePage(), | |
); | |
}, | |
); | |
} | |
} | |
class _HomePage extends StatelessWidget { | |
const _HomePage({Key? key}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: const Text('Demo'), | |
), | |
bottomNavigationBar: BottomNavigationBar( | |
items: const <BottomNavigationBarItem>[ | |
BottomNavigationBarItem( | |
icon: Icon(Icons.add), | |
label: 'First', | |
), | |
BottomNavigationBarItem( | |
icon: Icon(Icons.access_alarm), | |
label: 'Two', | |
), | |
BottomNavigationBarItem( | |
icon: Icon(Icons.ac_unit), | |
label: 'Three', | |
), | |
], | |
), | |
body: Center( | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
const Text( | |
'Here are some widgets for you:', | |
), | |
Switch( | |
value: true, | |
onChanged: (_) {}, | |
), | |
Checkbox( | |
value: true, | |
onChanged: (_) {}, | |
), | |
ElevatedButton( | |
onPressed: () {}, | |
child: const Text('Material button'), | |
), | |
], | |
), | |
), | |
floatingActionButton: FloatingActionButton( | |
onPressed: () {}, | |
tooltip: 'Increment', | |
child: const Icon(Icons.add), | |
), | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.materialyou_demo | |
import android.os.Build | |
import androidx.core.content.res.ResourcesCompat | |
import io.flutter.embedding.android.FlutterActivity | |
import io.flutter.embedding.engine.FlutterEngine | |
import io.flutter.plugin.common.MethodChannel | |
class MainActivity : FlutterActivity() { | |
private val CHANNEL = "com.example.app/colors" | |
override fun configureFlutterEngine(flutterEngine: FlutterEngine) { | |
super.configureFlutterEngine(flutterEngine) | |
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { | |
call, | |
result -> | |
when (call.method) { | |
"getMaterialYouColors" -> result.success(getMaterialYouColors()) | |
else -> result.notImplemented() | |
} | |
} | |
} | |
private fun getMaterialYouColors(): String? { | |
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { | |
return null | |
} | |
return mapOf( | |
"system_accent1_0" to android.R.color.system_accent1_0, | |
"system_accent1_10" to android.R.color.system_accent1_10, | |
"system_accent1_50" to android.R.color.system_accent1_50, | |
"system_accent1_100" to android.R.color.system_accent1_100, | |
"system_accent1_200" to android.R.color.system_accent1_200, | |
"system_accent1_300" to android.R.color.system_accent1_300, | |
"system_accent1_400" to android.R.color.system_accent1_400, | |
"system_accent1_500" to android.R.color.system_accent1_500, | |
"system_accent1_600" to android.R.color.system_accent1_600, | |
"system_accent1_700" to android.R.color.system_accent1_700, | |
"system_accent1_800" to android.R.color.system_accent1_800, | |
"system_accent1_900" to android.R.color.system_accent1_900, | |
"system_accent1_1000" to android.R.color.system_accent1_1000, | |
"system_accent2_0" to android.R.color.system_accent2_0, | |
"system_accent2_10" to android.R.color.system_accent2_10, | |
"system_accent2_50" to android.R.color.system_accent2_50, | |
"system_accent2_100" to android.R.color.system_accent2_100, | |
"system_accent2_200" to android.R.color.system_accent2_200, | |
"system_accent2_300" to android.R.color.system_accent2_300, | |
"system_accent2_400" to android.R.color.system_accent2_400, | |
"system_accent2_500" to android.R.color.system_accent2_500, | |
"system_accent2_600" to android.R.color.system_accent2_600, | |
"system_accent2_700" to android.R.color.system_accent2_700, | |
"system_accent2_800" to android.R.color.system_accent2_800, | |
"system_accent2_900" to android.R.color.system_accent2_900, | |
"system_accent2_1000" to android.R.color.system_accent2_1000, | |
"system_accent3_0" to android.R.color.system_accent3_0, | |
"system_accent3_10" to android.R.color.system_accent3_10, | |
"system_accent3_50" to android.R.color.system_accent3_50, | |
"system_accent3_100" to android.R.color.system_accent3_100, | |
"system_accent3_200" to android.R.color.system_accent3_200, | |
"system_accent3_300" to android.R.color.system_accent3_300, | |
"system_accent3_400" to android.R.color.system_accent3_400, | |
"system_accent3_500" to android.R.color.system_accent3_500, | |
"system_accent3_600" to android.R.color.system_accent3_600, | |
"system_accent3_700" to android.R.color.system_accent3_700, | |
"system_accent3_800" to android.R.color.system_accent3_800, | |
"system_accent3_900" to android.R.color.system_accent3_900, | |
"system_accent3_1000" to android.R.color.system_accent3_1000, | |
"system_neutral1_0" to android.R.color.system_neutral1_0, | |
"system_neutral1_10" to android.R.color.system_neutral1_10, | |
"system_neutral1_50" to android.R.color.system_neutral1_50, | |
"system_neutral1_100" to android.R.color.system_neutral1_100, | |
"system_neutral1_200" to android.R.color.system_neutral1_200, | |
"system_neutral1_300" to android.R.color.system_neutral1_300, | |
"system_neutral1_400" to android.R.color.system_neutral1_400, | |
"system_neutral1_500" to android.R.color.system_neutral1_500, | |
"system_neutral1_600" to android.R.color.system_neutral1_600, | |
"system_neutral1_700" to android.R.color.system_neutral1_700, | |
"system_neutral1_800" to android.R.color.system_neutral1_800, | |
"system_neutral1_900" to android.R.color.system_neutral1_900, | |
"system_neutral1_1000" to android.R.color.system_neutral1_1000, | |
"system_neutral2_0" to android.R.color.system_neutral2_0, | |
"system_neutral2_10" to android.R.color.system_neutral2_10, | |
"system_neutral2_50" to android.R.color.system_neutral2_50, | |
"system_neutral2_100" to android.R.color.system_neutral2_100, | |
"system_neutral2_200" to android.R.color.system_neutral2_200, | |
"system_neutral2_300" to android.R.color.system_neutral2_300, | |
"system_neutral2_400" to android.R.color.system_neutral2_400, | |
"system_neutral2_500" to android.R.color.system_neutral2_500, | |
"system_neutral2_600" to android.R.color.system_neutral2_600, | |
"system_neutral2_700" to android.R.color.system_neutral2_700, | |
"system_neutral2_800" to android.R.color.system_neutral2_800, | |
"system_neutral2_900" to android.R.color.system_neutral2_900, | |
"system_neutral2_1000" to android.R.color.system_neutral2_1000 | |
) | |
.map { (name, id) -> | |
val color = ResourcesCompat.getColor(resources, id, theme) | |
val colorHex = Integer.toHexString(color) | |
return@map "\"$name\": \"#$colorHex\"" | |
} | |
.joinToString(separator = ",", prefix = "{", postfix = "}") | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:convert'; | |
import 'package:flutter/foundation.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter/services.dart'; | |
const platform = MethodChannel('com.example.app/colors'); | |
Future<MaterialYouPalette?> getMaterialYouColor() async { | |
// Material You colors are available on Android only | |
if (defaultTargetPlatform != TargetPlatform.android) return null; | |
try { | |
final data = await platform.invokeMethod('getMaterialYouColors'); | |
if (data == null) return null; | |
final Map<String, dynamic> items = (json.decode(data) as Map<String, dynamic>); | |
return MaterialYouPalette( | |
accent1: items.getAccent1(), | |
accent2: items.getAccent2(), | |
accent3: items.getAccent3(), | |
neutral1: items.getNeutral1(), | |
neutral2: items.getNeutral2(), | |
); | |
} on PlatformException catch (_) { | |
return null; | |
} | |
} | |
class MaterialYouPalette { | |
final MaterialColor accent1; | |
final MaterialColor accent2; | |
final MaterialColor accent3; | |
final MaterialColor neutral1; | |
final MaterialColor neutral2; | |
MaterialYouPalette({ | |
required this.accent1, | |
required this.accent2, | |
required this.accent3, | |
required this.neutral1, | |
required this.neutral2, | |
}); | |
} | |
int _parseHexString(String value) => int.parse(value.substring(3, 9), radix: 16) + 0xFF000000; | |
extension _ColorExtractionExtension on Map<String, dynamic> { | |
Color getColor(String colorName) { | |
final value = this[colorName]; | |
final parsed = _parseHexString(value); | |
return Color(parsed); | |
} | |
MaterialColor getAccent1() { | |
return MaterialColor( | |
_parseHexString(this['system_accent1_100']), | |
<int, Color>{ | |
50: getColor('system_accent1_50'), | |
100: getColor('system_accent1_100'), | |
200: getColor('system_accent1_200'), | |
300: getColor('system_accent1_300'), | |
400: getColor('system_accent1_400'), | |
500: getColor('system_accent1_500'), | |
600: getColor('system_accent1_600'), | |
700: getColor('system_accent1_700'), | |
800: getColor('system_accent1_800'), | |
900: getColor('system_accent1_900'), | |
}, | |
); | |
} | |
MaterialColor getAccent2() { | |
return MaterialColor( | |
_parseHexString(this['system_accent2_100']), | |
<int, Color>{ | |
50: getColor('system_accent2_50'), | |
100: getColor('system_accent2_100'), | |
200: getColor('system_accent2_200'), | |
300: getColor('system_accent2_300'), | |
400: getColor('system_accent2_400'), | |
500: getColor('system_accent2_500'), | |
600: getColor('system_accent2_600'), | |
700: getColor('system_accent2_700'), | |
800: getColor('system_accent2_800'), | |
900: getColor('system_accent2_900'), | |
}, | |
); | |
} | |
MaterialColor getAccent3() { | |
return MaterialColor( | |
_parseHexString(this['system_accent3_100']), | |
<int, Color>{ | |
50: getColor('system_accent3_50'), | |
100: getColor('system_accent3_100'), | |
200: getColor('system_accent3_200'), | |
300: getColor('system_accent3_300'), | |
400: getColor('system_accent3_400'), | |
500: getColor('system_accent3_500'), | |
600: getColor('system_accent3_600'), | |
700: getColor('system_accent3_700'), | |
800: getColor('system_accent3_800'), | |
900: getColor('system_accent3_900'), | |
}, | |
); | |
} | |
MaterialColor getNeutral1() { | |
return MaterialColor( | |
_parseHexString(this['system_neutral1_100']), | |
<int, Color>{ | |
50: getColor('system_neutral1_50'), | |
100: getColor('system_neutral1_100'), | |
200: getColor('system_neutral1_200'), | |
300: getColor('system_neutral1_300'), | |
400: getColor('system_neutral1_400'), | |
500: getColor('system_neutral1_500'), | |
600: getColor('system_neutral1_600'), | |
700: getColor('system_neutral1_700'), | |
800: getColor('system_neutral1_800'), | |
900: getColor('system_neutral1_900'), | |
}, | |
); | |
} | |
MaterialColor getNeutral2() { | |
return MaterialColor( | |
_parseHexString(this['system_neutral2_100']), | |
<int, Color>{ | |
50: getColor('system_neutral2_50'), | |
100: getColor('system_neutral2_100'), | |
200: getColor('system_neutral2_200'), | |
300: getColor('system_neutral2_300'), | |
400: getColor('system_neutral2_400'), | |
500: getColor('system_neutral2_500'), | |
600: getColor('system_neutral2_600'), | |
700: getColor('system_neutral2_700'), | |
800: getColor('system_neutral2_800'), | |
900: getColor('system_neutral2_900'), | |
}, | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@aednlaxer oops sorry, set to public now