Flutter: SliverPersistentHeader перестраивается при прокрутке - PullRequest
0 голосов
/ 03 мая 2018

Я создал небольшой тестовый пример для этой проблемы, с которой я столкнулся. Из рисунка ниже видно, что приложение Flutter имеет только верхний заголовок. Когда я опускаю, чтобы обновить, заголовок не перестраивается сам. Однако, когда я перемещаю заголовок вверх, заголовок перестраивается много раз. Также обратите внимание, что я нигде не вызывал setState () в моем коде, поэтому я не уверен, откуда он знает, что ему нужно восстанавливать себя, когда я нажимаю прокрутку вверх.

Я бы хотел, чтобы заголовок вообще не перестраивался, поскольку нет причин, по которым он должен сам перестраиваться. Он статичен / не имеет состояния и не должен меняться вообще. Размер заголовка также не должен изменяться (следовательно, extendedHeight и collapsedHeight одинаковы для 136.0).

enter image description here

Вот пример кода, который я использовал для вас, чтобы воссоздать это:

import 'package:meta/meta.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'dart:math' as math;
import 'dart:async';

class _TestHeader extends SliverPersistentHeaderDelegate {
  _TestHeader({
    @required this.collapsedHeight,
    @required this.expandedHeight,
    @required this.showHeading,
  });

  bool showHeading;
  final double expandedHeight;
  final double collapsedHeight;

  @override
  double get minExtent => collapsedHeight;

  @override
  double get maxExtent => math.max(expandedHeight, minExtent);

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    print("rebuilding headings");
    return new SafeArea(
        child: Column(children: <Widget>[
      const SizedBox(height: 24.0),
      new GestureDetector(
        onTap: () {
        },
        child: new Container(
          decoration: const BoxDecoration(
            color: CupertinoColors.white,
            border: const Border(
              top: const BorderSide(color: const Color(0xFFBCBBC1), width: 0.0),
              bottom:
                  const BorderSide(color: const Color(0xFFBCBBC1), width: 0.0),
            ),
          ),
          height: 44.0,
          child: new Padding(
            padding:
                const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
            child: new SafeArea(
              top: false,
              bottom: false,
              child: new Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: const <Widget>[
                  const Text(
                    'This is my heading',
                    style: const TextStyle(color: CupertinoColors.activeBlue, fontSize: 16.0),
                  )
                ],
              ),
            ),
          ),
        ),
      ),
    ]));
  }

  @override
  bool shouldRebuild(@checked _TestHeader oldDelegate) {
//    return false;
    return expandedHeight != oldDelegate.expandedHeight ||
        collapsedHeight != oldDelegate.collapsedHeight;
  }
}

class TestHeaderPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new TestHeaderState();
  }
}


class TestHeaderState extends State<TestHeaderPage> {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new CupertinoPageScaffold(
      //i will need to convert this to a sliver list to make this work properly.
        backgroundColor: const Color(0xFFEFEFF4),
        navigationBar: new CupertinoNavigationBar(
          middle: new Text('Test Headers'),
        ),
        child: new SafeArea(
          child: new CustomScrollView(slivers: <Widget>[
            new CupertinoRefreshControl(onRefresh: () {
              print("pulling on refresh");
              return Future<void>(() {});
                }),
            new SliverPersistentHeader(
                delegate: new _TestHeader(
                    collapsedHeight: 136.0,
                    expandedHeight: 136.0,
                    showHeading: true)),
          ]),
        ));
  }

}

1 Ответ

0 голосов
/ 03 мая 2018

Это совершенно нормально.

Ваш _TestHeader является , а не виджетом. Тот факт, что у него есть метод build, не означает, что он один. :)

Вы расширили SliverPersistentHeaderDelegate, который используется для сборки SliverPersistentHeader.

Дело в том, что SliverPersistentHeader это не также виджет. Это осколок, который представляет собой другой способ отображения объектов на экране.

И, в случае SliverPersistentHeader, это особая разновидность ленты, которая перестраивается при изменении смещения прокрутки. То есть потенциально обрабатывать определенные анимации прокрутки. Такие как прокрутка вверх, чтобы заголовок исчез. И прокрутите вниз, чтобы сделать его обратно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...