這是我參與8月更文挑戰的27天,活動詳情檢視:8月更文挑戰
在flutter中,幾乎每個widget都有一個Key,但是我們使用的時候一般不會傳Key , 那麼這個Key,它到底是幹什麼用的呢? 幾乎每個widget都有,但我們又很少用到它. 那到底什麼時候才需要用呢?
接下來,我們看一下,在需要Key的時候不用key,會發生什麼情況.
先舉個常見的例子:
Column(
children: [
Container(width: 100, height: 100,color: Colors.red),
Container(width: 100, height: 100,color: Colors.blue),
]
),
複製程式碼
如果有上面一段程式碼,那麼會顯示兩個方塊,如圖:
如果把兩個Container
調換位置,那麼UI上,兩個方塊也會換位置.這個沒什麼說的,很容易理解.
那如果是兩個稍微複雜的widget呢?
現在建立一個新的Wdiget:
class Box extends StatefulWidget {
final Color color;
const Box(this.color, {Key? key}) : super(key: key);
@override
_BoxState createState() => _BoxState();
}
class _BoxState extends State<Box> {
int count = 0;
@override
Widget build(BuildContext context) {
return Container(
width: 100,
height: 100,
color: widget.color,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('$count', style: TextStyle(color: Colors.white)),
IconButton(
onPressed: () {
setState(() {
count++;
});
},
icon: Icon(Icons.add),
)
],
));
}
}
複製程式碼
這個Widget內部包含一個count
,由自己管理它的狀態,並且有一個方法,可以改變這個值.
程式碼如下:
Column(
children: [
Box(Colors.red),
Box(Colors.blue),
],
)
複製程式碼
現在用這個Widget替代上面的Container
, 然後分別改變它們的值:
然後我們把兩個widget互換位置,看看之後的效果:
可以看到,它的顏色雖然換了,但是數字卻沒有互換,似乎不是我們期望的效果.
我們再嘗試改變一下程式碼
Column(
children: [
Box(Colors.red),
Box(Colors.blue),
Box(Colors.red),
],
)
複製程式碼
然後我們把第一個box,也就是紅色的widget去掉,hotreload一下, 會是什麼樣呢?
很神奇,紅色的確實消失了,但是按理說應該第一個去掉, 而藍色的2和紅色的3留下,然而卻留下了前兩個,並且數值還是第一個和第二個.
看起來,Flutter已經分不清誰是誰了,可是在我們看來,這裡並沒有複雜的邏輯.
那我們如果換成3個紅色的box呢? 把程式碼改成這樣:
Column(
children: [
Box(Colors.red),
Box(Colors.red),
Box(Colors.red),
],
)
複製程式碼
然後我們再刪掉第一個,程式碼就變成了:
Column(
children: [
Box(Colors.red),
Box(Colors.red),
],
)
複製程式碼
如果不是自己親手刪除的,根本不知道是哪個不見了.只知道是少了一個.
如果我們依然像之前一樣,去調換順序呢? UI沒有改變, 可是調換之後程式碼並沒有變化,這麼看 似乎UI不變又不奇怪了. 程式碼都沒有變化,你指望UI有什麼變化呢?
好像找到了一點靈感, 是不是說明Flutter
不能靠顏色來辨別是哪個widget
,或者說顏色不能作為widget的唯一標識. 此時我們需要一個uuid
來區分不同的widget
, 而這 就是key
的作用了.
我們如果給widget分別傳入不同的key, 就相當於各自有了一個id, 如果這3個id不同,那麼flutter也就不會混淆它們了.
Flutter有幾種不同的key,我會在後面為大家介紹.
之前定義box元件的時候,已經定義了一個key
的引數, 此時我們分別傳入不同的key
Box(Colors.red,key: ValueKey(1)),
Box(Colors.red,key: ValueKey(2)),
Box(Colors.red,key: ValueKey(3)),
複製程式碼
因為有了key,flutter也就能區分它們了, 現在我們無論是調換還是刪除其中的widget
, flutter的變化就都會朝著我們預期的方向發展了.
在實際開發中,我們也會遇到不同widget混淆的問題,一般情況下, 加一個ValueKey
就可以解決了.
至於有什麼情況加ValueKey
不能解決,我們後面也會介紹到.