Обновления на экране переносятся, ListView и GridView - нет. Почему? - PullRequest
1 голос
/ 13 апреля 2020

Мое приложение

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(home: Scaffold(body: Grid())));

class Grid extends StatefulWidget {
  @override
  _GridState createState() => _GridState();
}

class _GridState extends State<Grid> {

  List<Widget> pieces = [Text('a'), Text('b'), Text('c')];

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: GestureDetector(
        onTap: () => setState(() => pieces[0] = Text('*')),
        child: Wrap(children: pieces),
        // child: ListView(children: pieces),
        // child: GridView.count(crossAxisCount: 3, children: pieces),
      ),
    );
  }
}

Проблема

После того, как я коснусь Wrap, на экране появится «*» - как и ожидалось

Когда я заменяю Обтекание либо ListView, либо GridView, «а» не меняется. Почему?

Одинаковое поведение как в 'stable', так и в 'master'

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.12.13+hotfix.9, on Linux, locale en_GB.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
[✓] Android Studio (version 3.6)
[✓] IntelliJ IDEA Community Edition (version 2019.3)
[✓] VS Code (version 1.44.0)
[✓] Connected device (1 available)

• No issues found!
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, v1.18.0-5.0.pre.89, on Linux, locale en_GB.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
[✓] Android Studio (version 3.6)
[✓] IntelliJ IDEA Community Edition (version 2019.3)
[✓] VS Code (version 1.44.0)
[✓] Connected device (1 available)

• No issues found!

Кажется, что ключи не помогают

Кто-то написал и предложил использовать ключи - но удалил пост, прежде чем я смог поблагодарить их. Использование таких ключей ...

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(home: Scaffold(body: Grid())));

class Grid extends StatefulWidget {
  @override
  _GridState createState() => _GridState();
}

class _GridState extends State<Grid> {

  List<Widget> pieces = [Text('a', key:UniqueKey()), Text('b', key:UniqueKey()), Text('c', key:UniqueKey())];

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: GestureDetector(
        onTap: () => setState(() => pieces[0] = Text('*', key:UniqueKey())),
        child: Wrap(children: pieces),
        // child: ListView(children: pieces),
        // child: GridView.count(crossAxisCount: 3, children: pieces),
      ),
    );
  }
}

... не имеет значения.

Поскольку Wrap сильно отличается?

Согласно документации Flutter наследование:

  • Объект Diagnosticable DiagnosticableTree Widget RenderObjectWidget MultiChildRenderObjectWidget Обтекание

  • 1032 * Объект Diagnosticable ДиагностическийTree Виджет *

  • Объект Diagnosticable DiagnosticableTree Widget StatelessWidget ScrollView BoxScrollView GridView

Таким образом, ListView и GridView сильно отличаются от Wrap. Это может объяснить проблему? Если да, то как ее решить?

Ответы [ 2 ]

0 голосов
/ 13 апреля 2020

попробуйте использовать ValueListenableBuilder<T> class. он может reRender там, где вам нужно, без перестройки всего дерева виджетов, что было бы замечательно, если вы используете дорогие виджеты на текущей странице.

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('title')
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('You're list should be generating below :'),
            ValueListenableBuilder(
              builder: (BuildContext context, int value, Widget child) {
                // This builder will only get called when the index
                // is updated.
                return Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    Text('pieces[index]'),
                    child,
                  ],
                );
              },
              valueListenable: _counter,
              // The child parameter is most helpful if the child is
              // expensive to build and does not depend on the value from
              // the notifier.
              child: expensiveWidget,
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.plus_one),
        onPressed: () => index++,
      ),
    );
  }
}

вы также можете увидеть полные документы здесь

0 голосов
/ 13 апреля 2020

Я думаю, вам нужно добавить уникальное свойство key в GridView, например,

GridView.count(crossAxisCount: 3, children: pieces, key: UniqueKey());

или использовать конструктор GridView.builder в другом месте

child: GridView.builder(
  itemCount: 3,
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
  itemBuilder: (context, index) => pieces[index],
),
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...