Flutter ListView.Builder приводит к прерывистой прокрутке. Как сделать прокрутку плавной?

Я пытаюсь создать приложение, в котором будет загружаться список бронирований. Когда пользователь прокручивает эти бронирования, прокрутка очень прерывистая. Я провел тестирование во всех режимах отладки, профиля и выпуска, но проблема с прерывистой прокруткой все еще остается. Это верно как для iOS, так и для Android. Вот что я уже пробовал -

  1. Я уже пробовал использовать const AlwaysScrollableScrollPhysics (),
  2. Пробовал использовать без анимации и с анимацией. В обоих случаях присутствует прерывистая прокрутка.
  3. Я пробовал cached.network.image. Присутствует прерывистая прокрутка.

Конструктору ListView требуется более 16 мсек для построения ListTile даже в режиме профиля.

Наложение производительности ListView

return ListView.builder(
      physics: const AlwaysScrollableScrollPhysics(),
      itemCount: widget.bookings.length,
      scrollDirection: Axis.vertical,
      itemBuilder: (context, int index) {
        var count = 10;
        var animation = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
            parent: animationController,
            curve: Interval((1 / count) * index, 1.0,
                curve: Curves.fastOutSlowIn)));
        animationController.forward();

        return BookingListCard(
          booking: widget.bookings[index],
          bookings: widget.bookings,
          animation: animation,
          animationController: animationController,
        );
      },
    );
AnimatedBuilder(
      animation: animationController,
      builder: (BuildContext context, Widget child) {
        return FadeTransition(
          opacity: animation,
          child: new Transform(
            transform: new Matrix4.translationValues(
                0.0, 50 * (1.0 - animation.value), 0.0),
            child: Padding(
              padding:
                  const EdgeInsets.only(left: 0, right: 0, top: 0, bottom: 0),
              child: InkWell(
                splashColor: Colors.transparent,
                onTap: () {
                  callback();
                },
                child: Padding(
                  padding: const EdgeInsets.only(top: 8.0),
                  child: Card(
                    color: AppTheme.halfWhite,
                    elevation: 0,
                    child: ListTile(
                      onTap: () {
                        Navigator.of(context)
                            .push(_createRoute(booking, booking.id));
                      },
                      leading: Container(
                        width: _size,
                        height: _size,
                        decoration: BoxDecoration(
                          shape: BoxShape.circle,
                          image: DecorationImage(
                            image: NetworkImage(booking.guest.imageUrl),
                            fit: BoxFit.fill,
                          ),
                        ),
                      ),
                      title: Padding(
                        padding: const EdgeInsets.only(top: 10.0),
                        child: Text(
                          booking.guest.firstName,
                          style: AppTheme.title,
                        ),
                      ),
                      subtitle: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: <Widget>[
                          Row(
                            children: <Widget>[
                              Text(
                                '${(DateFormat("E, d MMM").format(DateTime.parse(booking.checkIn))).toUpperCase()}  ',
                                style: AppTheme.caption,
                              ),
                              Image.asset(
                                "assets/images/arrow.png",
                                width: 12,
                                height: 12,
                              ),
                              Text(
                                '  ${(DateFormat("E, d MMM").format(DateTime.parse(booking.checkOut))).toUpperCase()}',
                                style: AppTheme.caption,
                              )
                            ],
                          ),
                          Padding(
                            padding:
                                const EdgeInsets.only(top: 8.0, bottom: 8.0),
                            child: DashedDivider(
                                color: Colors.black.withOpacity(0.6),
                                dashWidth: 0.1),
                          ),
                          Text(
                            '${(booking.status).toUpperCase()}',
                            style: TextStyle(
                              color: statusColorFinder(booking.status),
                              fontFamily: AppTheme.fontName,
                              fontWeight: FontWeight.bold,
                              fontSize: 12,
                              letterSpacing: 0.4,
                              height: 0.9,
                            ),
                          ),
                        ],
                      ),
                      // trailing: Icon(Icons.more_vert),
                      trailing: booking.status == 'Pending' ? MyBullet() : null,
                      isThreeLine: false,
                    ),
                  ),
                ),
              ),
            ),
          ),
        );
      },
    );

person LIONEL VSV    schedule 23.12.2019    source источник
comment
пробовали самый простой ListView.builder пример из официальной документации? он тоже идет рывками?   -  person pskink    schedule 23.12.2019
comment
Это все еще изменчиво с примером из официальной документации   -  person LIONEL VSV    schedule 23.12.2019
comment
так у вас только один ListView и больше ничего? без асинхронных задач, без изоляторов и т. д.?   -  person pskink    schedule 23.12.2019
comment
Почему ты снова и снова объявляешь анимацию? просто объявите его один раз в своем классе состояний и повторно используйте переменную вместо того, чтобы определять снова и снова.   -  person OMi Shah    schedule 23.12.2019


Ответы (1)


При работе в режиме профиля, способном отследить проблему, я сгенерировал пунктирную строку с помощью построителя списков, а не с помощью contianer, который был причиной задержки, заменил следующий код

 DashedDivider(color: Colors.black.withOpacity(0.6),
dashWidth: 0.1)

с этим

Container(color: Colors.black45,
height: 1,
width: double.maxFinite,
)
person LIONEL VSV    schedule 24.12.2019
comment
Итак, я спрашивал вас о самом простом ListView.builder примере из официальной документации, почему вы тоже сказали, что он нестабильный? - person pskink; 24.12.2019
comment
В официальном примере также в некоторых местах во время прокрутки требуется более 50 мс, что приводит к прерывистому - person LIONEL VSV; 24.12.2019
comment
Так что, если простейший пример нестабилен, ваш гораздо более сложный код тоже будет нестабильным, вам не кажется? Я имею в виду, что в вашей среде разработки должно быть что-то не так - person pskink; 24.12.2019
comment
Да, для сложного я смог получить менее 20 мс, что нормально, но не правильное решение. Для среды разработки я пробовал с двумя разными компьютерами, все то же самое - person LIONEL VSV; 24.12.2019
comment
Похоже, это было исправлено в v1.12.13. Тебе сейчас лучше? github.com/flutter/flutter/issues/22314 - person Gumby The Green; 22.02.2020