Що таке Ключі у класі віджетів без громадянства?


81

У документації до флаттера є зразок коду для підкласу віджетів без стану, як показано:

class GreenFrog extends StatelessWidget {
  const GreenFrog({ Key key }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Container(color: const Color(0xFF2DBD3A));
  }
}

і це

class Frog extends StatelessWidget {
  const Frog({
    Key key,
    this.color: const Color(0xFF2DBD3A),
    this.child,
  }) : super(key: key);

  final Color color;

  final Widget child;

  @override
  Widget build(BuildContext context) {
    return new Container(color: color, child: child);
  }
}

Що таке ключ і коли слід використовувати цей суперконструктор? Здається, якщо у вас є власний конструктор, ви повинні мати {Key key}, чому? Я бачив інші приклади, коли ключове слово super не використовується, тому тут моя плутанина.


У певному сенсі, концепція схожа на ключ в React stackoverflow.com/questions/28329382 / ...
onmyway133

1
Ці хлопці могли б використовувати ключі для підвищення продуктивності .... варто поглянути на medium.com/flutter-community/…
stuckedoverflow

Відповіді:


115

TLDR: Всі віджети повинні мати в Key keyякості додаткового параметра або їх конструктора. Keyце те, що використовується механізмом флаттера на етапі розпізнавання того, який віджет у списку змінено.


Це корисно , коли у вас є список ( Column, Rowнезалежно) віджетів одного і того ж типу , що потенційно може отримати видалені / вставленим.

Скажімо, у вас це є (код не працює, але ви зрозуміли):

AnimatedList(
  children: [
    Card(child: Text("foo")),
    Card(child: Text("bar")),
    Card(child: Text("42")),
  ]
)

Потенційно ви можете видалити будь-який з цих віджетів окремо, провевши пальцем.

Справа в тому, що в нашому списку є анімація, коли дитину вилучають. Тож давайте знімемо «бар».

AnimatedList(
  children: [
    Card(child: Text("foo")),
    Card(child: Text("42")),
  ]
)

Проблема: без цього Key, трепет не зможе дізнатися, чи Rowзник другий елемент вашого . Або якщо це останнє, що зникло, а друге змінило дитину.

Отже, без цього у Keyвас може бути помилка, коли анімація виходу буде відтворюватися на останньому елементі!


Ось де Key відбувається.

Якщо ми знову почнемо наш приклад, використовуючи ключ, ми отримаємо таке:

AnimatedList(
  children: [
    Card(key: ObjectKey("foo"), child: Text("foo")),
    Card(key: ObjectKey("bar"), child: Text("bar")),
    Card(key: ObjectKey("42"), child: Text("42")),
  ]
)

зверніть увагу, що ключовим є не дочірній індекс, а щось унікальне для елемента.

З цього моменту, якщо ми знову видалимо "бар", будемо мати

AnimatedList(
  children: [
    Card(key: ObjectKey("foo"), child: Text("foo")),
    Card(key: ObjectKey("42"), child: Text("42")),
  ]
)

Завдяки keyприсутності, мерехтливий двигун тепер точно знає, який віджет було видалено. І тепер наша анімація відпустки буде правильно грати на "стовпчику" замість "42".


1
Я починаю розуміти, що ви говорите, я також новачок у розробці мобільних пристроїв, так що голий зі мною. Щоб лише пояснити з вашого пояснення, тепер можна було розрізнити елементи картки, навіть незважаючи на те, що вони мали інший текст як їхня дитина? Отже, для вирішення цієї проблеми ключ використовується як унікальний ідентифікатор кожного елемента. Це правильно?
DanT29,

1
Точно так. Для розмежування віджетів за замовчуванням безлад використовує їх тип та індекс у списку, якщо ви не вказали ключ.
Rémi Rousselet

1
Має більше сенсу, у мене є ще одне питання, яке я оновив як Питання 2 у своєму початковому дописі. Здається, більш дартлангом ви можете спробувати пояснити це?
DanT29,

5
Чи додає флаттер ключ за замовчуванням?
Ішан Фернандо,

10
@IshanFernando ні. Але коли ключа немає, флетер використовує тип віджета, і його розташування в масиві як посилання.
Ремі Русселет,

12

Що таке ключі?

Ключі - це ідентифікатори віджетів. Вони є у всіх віджетів, а не лише у Віджетах без держави. Вони використовуються деревом Елементів, щоб визначити, чи можна віджет використовувати повторно, чи його потрібно відновити. Коли жоден ключ не вказаний (звичайний випадок), тоді для цього визначається тип віджета.

Навіщо використовувати Ключі?

Клавіші корисні для підтримання стану, коли кількість або позиція віджетів змінюється. Якщо ключа немає, фреймворк Flutter може заплутатися щодо того, який віджет змінено.

Коли використовувати ключі?

Використовуйте їх лише тоді, коли фреймворк потребує вашої допомоги, щоб знати, який віджет потрібно оновити.

Здебільшого вам не потрібно використовувати ключі. Оскільки ключі в основному корисні лише для підтримання стану, якщо у вас є віджет без громадянства, діти якого всі без громадянства, тоді немає необхідності використовувати на ньому ключ. Використання ключа в цьому випадку не завадить, але це також не допоможе.

Є кілька мікро-оптимізацій, які ви можете зробити за допомогою клавіш. Дивіться цю статтю .

Де використовувати ключі?

Помістіть ключ у ту частину дерева віджетів, де відбувається переупорядкування або додавання / видалення. Наприклад, якщо ви впорядковуєте елементи ListView, дочірніми елементами яких є віджети ListTile, додайте ключі до віджетів ListTile.

Які ключі використовувати?

Ключ - це просто ідентифікатор, але тип ідентифікатора можна змінювати.

ValueKey

ValueKey - це локальний ключ, який приймає просте значення, таке як рядок або ціле число.

ObjectKey

Якщо ваш віджет відображає складніші дані, ніж одне значення, тоді ви можете використовувати ObjectKey для цього віджета.

UniqueKey

Цей тип ключа гарантовано дасть вам кожен раз унікальний ідентифікатор. Якщо ви використовуєте його, покладіть його вbuild методі. Інакше ваш віджет ніколи не матиме однаковий ідентифікатор, тому дерево елементів ніколи не знайде відповідності для повторного використання.

GlobalKey

GlobalKeys можна використовувати для підтримки стану у вашому додатку, але використовуйте їх помірковано, оскільки вони схожі на глобальні змінні. Часто замість цього бажано використовувати рішення державного управління.

Приклади використання клавіш

Список літератури


4

Ключ - це необов’язковий параметр, необхідний для збереження стану у вашому дереві віджетів. Ви повинні використовувати їх, якщо хочете перемістити колекцію елементів у своєму дереві та зберегти їх стан.

Найкраще пояснення можна знайти в цьому відео Google, коли використовувати клавіші - Flutter Widgets 101 Ep. 4


4

Ключ - це об’єкт, який використовується для унікальної ідентифікації віджета.

Вони використовуються для доступу або відновлення стану В StatefulWidget(Здебільшого вони нам взагалі не потрібні, якщо наше дерево віджетів має всі віджети без громадянства). Існують різні типи ключів, які я спробую пояснити на основі використання.

Призначення ( key types)

1. Мутувати колекцію i.e. remove / add / reorder item to list у віджеті, який можна перетягнути, наприклад, перетягуваний список завдань, звідки вилучаються позначені елементи

➡️ ObjectKey, ValueKey & UniqueKey

2. Перемістіть віджет від одного Батька до іншого, зберігаючи його стан.

➡️ GlobalKey

3. Відобразити один і той же віджет на кількох екранах і утримуючи його стан.

➡️ GlobalKey

4. Перевірити форму.

➡️ GlobalKey

5. Ви хочете дати ключ, не використовуючи жодних даних.

➡️ UniqueKey

6. Якщо ви можете використовувати певні поля даних, такі як UUID користувачів, як унікальний ключ.

➡️ ValueKey

7. Якщо у вас немає жодного унікального поля для використання в якості ключа, але сам об’єкт є унікальним.

➡️ ObjectKey

8. Якщо у вас кілька форм або кілька віджетів одного типу, для яких потрібен GlobalKey.

➡️ GlobalObjectKey, LabeledGlobalKey whichever is appropriate, similar logic to ValueKey and ObjectKey

❌ Не використовуйте випадковий string/numberключ як ключ, це перешкоджає призначенню ключів ❌

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.