У піддереві є кілька героїв, які мають однаковий тег


128

Я намагаюся переходити з одного екрана на інший за допомогою маршруту. Коли я натискаю кнопку для переходу сторінки на вказаний маршрут, я отримую помилку

I/flutter ( 8790): Another exception was thrown: There are multiple heroes that share the same tag within a subtree.

Ось код:

Маршрути:

 <String, WidgetBuilder>{
    '/first':(BuildContext context) =>NavigatorOne() ,
    '/second':(BuildContext context) =>NavigatorTwo(),
    '/third':(BuildContext context) =>NavigatorThree(),

  },

Navigator.of(context).pushNamed('/first');
Navigator.of(context).pushNamed('/second');
Navigator.of(context).pushNamed('/third');

class NavigatorOne extends StatefulWidget {
  @override
  _NavigatorOneState createState() =>  _NavigatorOneState();
}

class _NavigatorOneState extends State<NavigatorOne> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(

      appBar: AppBar(),
      body: Container(
      color: Colors.green,
      child: RaisedButton(child: Text(' one 1'),onPressed: (){
        Navigator.of(context).pushNamed('/second');
      },),
    ),
    ); 
  }
}

І помилка:

══╡ EXCEPTION CAUGHT BY SCHEDULER LIBRARY ╞═════════════════════════════════════════════════════════ I/flutter (21786): The following assertion was thrown during a scheduler callback: I/flutter (21786): There are multiple heroes that share the same tag within a subtree. I/flutter (21786): Within each subtree for which heroes are to be animated (typically a PageRoute subtree), each Hero I/flutter (21786): must have a unique non-null tag. I/flutter (21786): In this case, multiple heroes had the following tag: <default FloatingActionButton tag>

Як я можу це вирішити?

Відповіді:


340

Я стикався з цим раніше, і тому, що у мене було дві FloatingActionкнопки на одному екрані, мені довелося додати властивість heroTag + значення на кожну, FloatingActionButtonщоб помилка зникла.

Приклад:

new FloatingActionButton(
    heroTag: "btn1",
    ...
)

new FloatingActionButton(
    heroTag: "btn2",
    ...
)

З прикладу коду, який ви вказали FloatingActionButton, не видно, що у вас є , але з помилки, схоже, посилається на нього:

I/flutter (21786): In this case, multiple heroes had the following tag: default FloatingActionButton tag

Можливо, ви використовували його на тій сторінці, до якої ви переходили, яка потім спричинила помилку. Зауважте, що якщо ви використовуєте програмний спосіб створення тегованих героїв, вам потрібно буде знайти спосіб присвоєння їм різних тегів. Наприклад, якщо у вас є ListView.builder()створення FloatingActionButtons, спробуйте передати тег з рядком форматування так що кожна кнопка має інший тег, наприклад: heroTag: "btn$index".

У будь-якому випадку сподівайтесь, що комусь допомагає.


9
Ви можете просто звести його нанівець: heroTag: null,
mik

14
Подібні проблеми були б і ListTileз Heroвнутрішньою частиною. це Heroне просто один герой, а він множиться на ваш items.length, тому мітка повинна бути'tag$index'
mrahimygk

як я можу додати героя всередину GridView?
Андрій

2
Оце Так! Я переходив до чорного екрану. Я знав, що екран завантажується належним чином, коли я поклав на нього звуковий файл для автоматичного відтворення для перевірки. Нарешті помітив це повідомлення про помилку "герой" і знайшов вашу відповідь - дякую! Дійсно дуже корисно.
Донна

Ти врятував мій день!
badelectron77

32

Ви можете встановити унікальний ідентифікатор або встановити лише null:

new FloatingActionButton(
heroTag: null,
...
)

16

Лише для читачів у майбутньому:

вдячний коментарю @ m.vincent, причиною цієї помилки для мене є те, що я використовував Hero, всередині SliverChildBuilderDelegateякого (очевидно) є індекс, тому я використовував індекс із таким тегом, 'tag$index'як цей

SliverChildBuilderDelegate(
    (BuildContext context, int index) {
      return Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Hero(
              tag: 'tagImage$index',
              child: Image.asset(
                'image source here',
              ),
            ),

ПРИМІТКА: це може статися з будь-яким віджетом із дочірніми елементами, створеними індексом, як ListView.Builder


Дякую, це дуже корисно. Коли ви переходите на наступну сторінку, пропустіть також індекс натискання. Для відповідності крана Тег героя та імені тегу героя наступної сторінки.
Абдулла Хан,

3

Для мене просто додавання унікального heroTagдо мого FloatingActionButtonsне працювало. У підсумку я завернув heroTagу Textвіджет, і це вирішило проблему для мене.

new FloatingActionButton(
    heroTag: Text("btn1"),
    ...
)

new FloatingActionButton(
    heroTag: Text("btn2"),
    ...
)

Це справді химерно.
Люк Пігетті,

2

Додайте скільки завгодно віджетів за допомогою тегів героїв, як Рядки

  Widget floatingButt(Function function, IconData icon, String heroTag) {
    return FloatingActionButton(
      onPressed: function,
      heroTag: heroTag,
      materialTapTargetSize: MaterialTapTargetSize.padded,
      backgroundColor: Constants.primaryColor, // from your values file
      child: Icon(
        icon,
        size: 36.0,
      ),
    );
  }

1

Я пройшов через ту саму помилку. Це через використання таких кнопок, як плаваюча кнопка дії кілька разів на одному екрані.
Раніше я використовував плаваючу кнопку дії, замість цього змінив її на детектор жестів, щоб використовувати ontap, щоб він працював

  GestureDetector(

              //backgroundColor: Colors.amber[100],
              onTap: add,
              child: Icon(
                FontAwesomeIcons.plus,
                size: 30,
              ),
            ),
            SizedBox(
              width: 20,
            ),
            GestureDetector(
             // heroTag: "btn2",
             // backgroundColor: Colors.amber[100],
              onTap: sub,
              child: Icon(FontAwesomeIcons.minus, size: 30),
            ),

Чи можете ви порівняти запропонований вами підхід із прийнятою відповіддю?
greybeard

0

Просто встановіть, tag: Uuid()якщо у вас є кілька елементів з однаковим тегом.

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