一、相信大家對(duì)App黑白化并不陌生,經(jīng)??梢钥吹酱髲S(chǎng)的App在一定的時(shí)候會(huì)呈現(xiàn)黑白樣式如下:


這種效果在原生開(kāi)發(fā)上大家肯定或多或少都了解過(guò),原理都是在根布局繪制的時(shí)候?qū)?huà)筆飽和度設(shè)置成0;具體實(shí)現(xiàn)大家可以搜一搜這里就不貼了。
二、下面就來(lái)說(shuō)說(shuō)在Flutter這一側(cè)需要怎么實(shí)現(xiàn)
- 原理和原生還是一樣都是將飽和度設(shè)置成0,不過(guò)在Flutter這實(shí)現(xiàn)起來(lái)會(huì)比在原生更加的簡(jiǎn)單。
- Flutter直接為我們提供了ColorFiltered組件(以Color作為源的混合模式Widget)。
- 只需要將ColorFiltered做為根組件(包裹MaterialApp)即可改變整個(gè)應(yīng)用的顏色模式。
實(shí)現(xiàn)的最終代碼如下
class SaturationWidget extends StatelessWidget {
final Widget child;
///value [0,1]
final double saturation;
const SaturationWidget({
required this.child,
this.saturation = 0,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ColorFiltered(
colorFilter: ColorFilter.matrix(_saturation(saturation)),
child: child,
);
}
///Default matrix
List<double> get _matrix => [
1, 0, 0, 0, 0, //R
0, 1, 0, 0, 0, //G
0, 0, 1, 0, 0, //B
0, 0, 0, 1, 0, //A
];
///Generate a matrix of specified saturation
///[sat] A value of 0 maps the color to gray-scale. 1 is identity.
List<double> _saturation(double sat) {
final m = _matrix;
final double invSat = 1 - sat;
final double R = 0.213 * invSat;
final double G = 0.715 * invSat;
final double B = 0.072 * invSat;
m[0] = R + sat;
m[1] = G;
m[2] = B;
m[5] = R;
m[6] = G + sat;
m[7] = B;
m[10] = R;
m[11] = G;
m[12] = B + sat;
return m;
}
}
- 通過(guò)4x5的R、G、B、A、顏色矩陣來(lái)生成一個(gè)colorFilter
- 最終通過(guò)飽和度的值來(lái)計(jì)算顏色矩陣(飽和度計(jì)算算法從Android原生copy過(guò)來(lái)的)這樣就輕松實(shí)現(xiàn)了整個(gè)App的黑白化(不過(guò)iOS的webview是不支持的)
三、最后來(lái)看下實(shí)現(xiàn)的效果
