Как предотвратить рендеринг данного виджета, когда поверх него во флаттере находится какой-то другой виджет? - PullRequest
2 голосов
/ 03 июня 2019

Я бы хотел иметь заголовки списка в качестве закрепленных заголовков.Фон данного заголовка должен быть прозрачным, и при прокрутке элемента списка «под» заголовок должен исчезнуть, и пользователь должен увидеть фоновое изображение за представлением списка.

Я использую пакет sticky_headers, чтобы получить липкийэффект заголовкаНо я только начинаю свое приключение с флаттера и мало знаю о рендеринге виджетов.

1 Ответ

0 голосов
/ 14 июня 2019

Мне удалось сделать это с помощью ShaderMask. Идея в том, что я вычисляю, где находится заголовок в моем элементе списка, и маскирую эту часть.

Важнейшая часть виджета списка:

  @override
  Widget build(BuildContext context) => ListView.builder(
      padding: _padding, itemCount: _sectionCount, itemBuilder: _sectionHeader);

  StickyHeader _sectionHeader(BuildContext context, int sectionIndex) {
    final GlobalKey eventListHeaderKey = GlobalKey();
    final GlobalKey shaderMaskKey = GlobalKey();
    final AppStyle appStyle = AppStyle.of(context);

    return StickyHeader(
        header: Container(
            key: eventListHeaderKey,
            child: _sectionHeaderBuilder(context, sectionIndex)),
        content: ShaderMask(
            key: shaderMaskKey,
            shaderCallback: (Rect rect) =>
                _listShader(appStyle, eventListHeaderKey, shaderMaskKey, rect),
            blendMode: BlendMode.dstIn,
            child: Container(
                child: ListView.builder(
                    physics: const NeverScrollableScrollPhysics(),
                    shrinkWrap: true,
                    itemCount: _sectionElementsCountHandler(sectionIndex),
                    itemBuilder: (BuildContext context, int index) =>
                        _elementBuilder(context, sectionIndex, index)))));
  }

  Shader _listShader(AppStyle appStyle, GlobalKey listHeaderKey,
      GlobalKey shaderMaskKey, Rect rect) {
    final RenderBox listHeaderRenderBox =
        listHeaderKey.currentContext.findRenderObject();
    final Offset offset = listHeaderRenderBox.localToGlobal(Offset.zero);

    final RenderBox shaderMaskRenderBox =
        shaderMaskKey.currentContext.findRenderObject();
    final Offset offset2 = shaderMaskRenderBox.globalToLocal(offset);

    return LinearGradient(
        begin: Alignment.topCenter,
        end: Alignment.bottomCenter,
        stops: <double>[
          0,
          (rect.top + offset2.dy) / rect.height,
          (rect.top + offset2.dy) / rect.height,
          1
        ],
        colors: <Color>[
          appStyle.colors.transparent,
          appStyle.colors.transparent,
          appStyle.colors.white,
          appStyle.colors.white
        ]).createShader(Rect.fromLTWH(0, 0, rect.width, rect.height));
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...