前言:
這是我參與8月更文挑戰的第 29 天,活動詳情檢視:8月更文挑戰。為應掘金的八月更文挑戰
,我準備在本月挑選 31
個以前沒有介紹過的元件,進行全面分析和屬性介紹。這些文章將來會作為 Flutter 元件集錄
的重要素材。希望可以堅持下去,你的支援將是我最大的動力~
一、ImageFiltered 元件
1. 認識 ImageFiltered 元件
上一篇說了 BackdropFilter 元件,它可以在子元件下方新增一個過濾層
,所以此效果無法作用於子元件。而 ImageFiltered
是將 過濾層
放在子元件上方,也就是過濾效果可以作用於子元件上。
它繼承自 SingleChildRenderObjectWidget
,必須傳入 imageFilter
引數,型別為 ImageFilter
。這和 BackdropFilter
元件中的 imageFilter
是一樣的。
2. ImageFiltered 元件的使用
如下是通過 ImageFiltered
對圖片進行模糊的效果,imageFilter
引數的使用和 BackdropFilter 一樣,這裡不再贅述。
1*1 | 2*2 | 3*3 | 5*5 |
---|---|---|---|
class ImageFilteredDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ImageFiltered(
imageFilter: ImageFilter.blur(
sigmaX: 2,
sigmaY: 2,
),
child: Image.asset(
'assets/images/sabar.webp',
fit: BoxFit.cover,
width: 150,
height: 150,
),
);
}
}
複製程式碼
另外 ImageFiltered
並不侷限於 Image
元件。如下將 FlutterUnit
整體使用 ImageFiltered
進行處理,這樣全應用都會有模糊效果。雖然這麼做沒有什麼太大的意義,只是說明 ImageFiltered
可以處理任意元件。
- | - | - |
---|---|---|
void main() {
WidgetsFlutterBinding.ensureInitialized();
//滾動效能優化 1.22.0
GestureBinding.instance?.resamplingEnabled = true;
runApp(BlocWrapper(
child: ImageFiltered(
imageFilter: ImageFilter.blur(
sigmaX: 2,
sigmaY: 2,
),
child: FlutterUnit(),
),
));
}
複製程式碼
3.ImageFiltered 元件原始碼實現
ImageFiltered
繼承自 SingleChildRenderObjectWidget
,內部維護 _ImageFilterRenderObject
渲染物件來實現新增濾色器功能。
在 _ImageFilterRenderObject#paint
中建立 ImageFilterLayer
物件 layer
,並將傳入的 imageFilter
設定給 layer
。通過 context.pushLayer
新增一個層,實現濾色器功能。
二、ColorFiltered 元件
1.認識 ColorFiltered 元件
ColorFiltered
繼承自 SingleChildRenderObjectWidget
,必須傳入 colorFilter
引數,型別為 ImageFilter
。
2. ColorFiltered 元件的使用
ColorFiltered
有四種構造方式,.srgbToLinearGamma
和 .linearToSrgbGamma
是固定的處理效果;.mode
是通過顏色和混合模式進行著色處理。通過 .matrix
可以進行顏色的矩陣變換。這塊比較複雜,不詳細展開,感興趣的可以看一下《Flutter 繪製指南 - 妙筆生花》 的第八章,有對著色器的詳細介紹。
//srgbToLinearGamma
ColorFiltered(
colorFilter: ColorFilter.srgbToLinearGamma(),
child: Image.asset(
'assets/images/sabar.webp',
fit: BoxFit.cover,
width: 150,
height: 150,
),
)
//linearToSrgbGamma
ColorFiltered(
colorFilter: ColorFilter.linearToSrgbGamma(),
child: Image.asset(
'assets/images/sabar.webp',
fit: BoxFit.cover,
width: 150,
height: 150,
),
)
//.matrix
ColorFiltered(
colorFilter: ColorFilter.matrix(<double>[
1,0,0,0,110,
0,1,0,0,110,
0,0,1,0,110,
0,0,0,1,0
]),
child: Image.asset(
'assets/images/sabar.webp',
fit: BoxFit.cover,
width: 150,
height: 150,
),
),
複製程式碼
同樣 ColorFiltered
並不侷限於 Image
元件。如下將 FlutterUnit
整體使用 ColorFiltered
進行灰色處理,這樣全應用
都會有著色效果,說明 ColorFiltered
可以處理任意元件。這在某些場景下還是非常有用的。
- | - | - |
---|---|---|
ColorFiltered(
colorFilter: ColorFilter.matrix(<double>[
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0, 0, 0, 1, 0,
]),
child: FlutterUnit(),
),
複製程式碼
其實有了 matrix
可以操作顏色變換,就會有很多可發揮的空間,它又可以作用於任何元件,做出全域性的懷舊色什麼的也不是不可以。matrix
這東西,有著無限的可能。
3.ColorFiltered 元件原始碼實現
可能會有人擔心效能什麼的,其實看了這麼多的 SingleChildRenderObjectWidget
,我們也能知道一些特點。ColorFiltered
是通過 _ColorFilterRenderObject
實現的。
在繪製時新增了一層 ColorFilterLayer
,進行著色處理。這就像是在眼前放一個紅色的膜片
,看到世界上所有的東西都帶紅色一樣,而不是膜片擁有改變世界的能力
,把世界上所有的東西真正被染成了紅色。
ColorFiltered
也是一樣,它只是一個遮罩層,並非所有的元件都一一被染成紅色,不用顧慮太多。Opacity
、ClipRect
、Transform
這類功能性的元件都是通過新增對應的層實現功能的,所以 ColorFilterLayer
也就是一個普通的 SingleChildRenderObjectWidget
。
那本文到這裡就結束了,謝謝觀看,明天見~