Skip to content

Instantly share code, notes, and snippets.

@aednlaxer
Last active Oct 5, 2021
Embed
What would you like to do?
Flutter app - get Material You colors via platform channel
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),
),
);
}
}
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 = "}")
}
}
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