2022年8月11日 星期四

Flutter學習10-2 key

 key對於部件的意義,就像每個人的身份證號碼一樣,你可以靠key找到那個部件,並取用這個部件的資訊,作為辨別這個部件使用,所以若在某範圍內,將key設為一樣,沒辦法達到辨別的作用,程式就會報錯。

key有LocalKey及GlobalKey 兩種,LocalKey是區域變數,只在限定的某些範圍中使用,就像是你的部件原來是放在Container裡面的Row布局,並設了一個LocalKey,這時候,你重寫程式,把Row改成了Column,位置移動了,因為程式原來的記憶你的LocalKey是在放在Row裡面,所以它就會在Row這個地方找,因為Row中它找不到,只好把這個值恢復成最初的狀態。
而GlobalKey則是全域的變數,同一個程式中都可以使用,就算移動也會保持它的狀態。

key又可分為下面三種:ValueKey、ObjectKey、UniqueKey

ValueKey和ObjectKey相似,第一個不同的是放置的類型。
第二個是值和內存的不同。
ValueKey對比的是ValueKey 的()裡面的值是否相等,而ObjectKey對比的是在記憶體的內存是否相等。意思是說ValueKey比較時,會看()你放的東西是不是一樣,如ValueKey(1)和ValueKey(1),又或者是ValueKey("一號")和ValueKey("一號")就是一樣的。
但ObjectKey對比時,除了比較值,還會去看你是不是儲存在同一個記憶體的值。

ValueKey的宣告方法:(類型是T,泛型,因此value要輸入什麼類型都可以)
每個部件都有key的屬性,因此一般不用特別宣告,使用如下:
Container(
height: 100,
width: 100,
color: Colors.red,
key:ValueKey(1), //keyValueKey(1)
),
Container(
height: 100,
width: 100,
color: Colors.blue,
key:ValueKey(2), //keyValueKey(2)
),

Container( height: 100,
width: 100,
color: Colors.blue,
key:ValueKey(3),),

ObjectKey的宣告方式:(類型是object,因此value只能輸入object)
Container(
height: 100,
width: 100,
color: Colors.red,
key:ObjectKey(1), //keyObjectKey(1)
),
Container(
height: 100,
width: 100,
color: Colors.blue,
key:ObjectKey(2), //keyObjectKey(2)
),

Container( height: 100,
width: 100,
color: Colors.blue,
key:ObjectKey(3)), //keyObjectKey(2)


UniqueKey的英文是指唯一的key,每次在重新建立的時候,都會給它一個新的key,那原來你依靠這個key所記錄的值就會不見。用在需要特別將key丟掉的情況。如在動畫時,你可以每次都要重新設一個變化,而動畫的原理是會判斷你是不是有轉變時,才會有變化,這時你在重新時用上UniqueKey,那它每次都會重新建立一個新的key,系統比對後,發現你是不同的東西,就會由原來的情況,變成你希望它變化的情況。


最後是GlobalKey,在使用它時要先宣告一個新的GlobalKey:
GlobalKey myGolobalKey= GlobalKey();

宣告好,你就可以把剛才宣告好的myglobalkey變數中,放在任何一個部件中的key屬性中,提供辨別的作用。如下:

Form(
key: myGolobalKey, //設置globalKey

使用GlobalKey有兩個好處,不是讓一個部件的key不會丟失它的值,二是可以透過這個key找到這個部件的內容,以便於讀取或是改變這個值,讓它在其它地方都是一樣的。
你可以依下列三種方法找到你要使用關於此部件的值。
如果是要取得widget。

globalkey.currentWidget as 你的Widget名稱。as 在指定你使用的是那個Widget,如form。

final Form formWidget = myGolobalKey.currentWidget as Form;  //宣告 formWidgety是一個Form widget,讓它指向Form

如果是要取得部件的context
globalkey.currentContext as 你的Widget名稱。
如:
final Form formContext = myGolobalKey.currentContext as Form;  //宣告 myGolobalKey為此部件的內容,包括上面提到widgetstate

如取得部件的state
final FormState formState = myGolobalKey.currentState as FormState;  //宣告 myGolobalKey是一個FormState類型,讓它指向FormState

key的教學影片可參考:


沒有留言:

張貼留言