Как программно свернуть или развернуть SliverPresistentHeader [пользовательская плавающая панель приложений]

#flutter #flutter-sliver #flutter-sliverappbar

#flutter #flutter-sliver #flutter-sliverappbar

Вопрос:

Я пытаюсь программно свернуть или развернуть SliverPresistantHeader со ссылкой на shrinkOffset значение. Я искал везде, чтобы найти, как реализовать эту функцию, но я не смог найти никакого решения (поэтому здесь я спрашиваю).

Вот мой код для моего пользовательского SliverPresistantHeaderDelegate:

 import 'package:bom/constants/constants.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

class BomAppHeader implements SliverPersistentHeaderDelegate {
  BomAppHeader({
    this.expandedHeight,
    this.title,
    this.body,
    @required this.notificationShade,
  });

  final double notificationShade;
  final double expandedHeight;
  final Widget title;
  final Widget body;

  @override
  double get maxExtent {
    if (expandedHeight == null || expandedHeight < kToolbarHeight) {
      return minExtent;
    } else {
      return notificationShade   expandedHeight;
    }
  }

  @override
  double get minExtent {
    return title == null
        ? notificationShade
        : notificationShade   kToolbarHeight;
  }

  double bodyOpacity(double shrinkOffset) {
    return max(0.0, 1 - (shrinkOffset / (maxExtent - minExtent)));
  }

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    // print(max(0.0, 1 - (shrinkOffset / (maxExtent - minExtent))));

    return Stack(
      fit: StackFit.expand,
      children: [
        Container(
          decoration: kAppBarDecoration,
        ),
        Opacity(
          opacity: bodyOpacity(shrinkOffset),
          child: Container(
            height: maxExtent > minExtent ? double.infinity : 0.0,
            margin: title == null
                ? EdgeInsets.only(top: notificationShade   2)
                : EdgeInsets.only(
                    top: notificationShade, bottom: kToolbarHeight),
            padding: EdgeInsets.all(8.0),
            child: body,
          ),
        ),
        Column(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
          SizedBox(
            height: notificationShade,
          ),
          Container(
            height: title == null ? 0.0 : kToolbarHeight,
            padding: EdgeInsets.all(5.0),
            child: title,
          ),
        ]),
      ],
    );
  }

  double titleOpacity(double shrinkOffset) {
    // simple formula: fade out text as soon as shrinkOffset > 0
    return 1.0 - max(0.0, shrinkOffset) / maxExtent;
    // more complex formula: starts fading out text when shrinkOffset > minExtent
    //return 1.0 - max(0.0, (shrinkOffset - minExtent)) / (maxExtent - minExtent);
  }

  @override
  bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
    return true;
  }

  @override
  // TODO: implement showOnScreenConfiguration
  PersistentHeaderShowOnScreenConfiguration get showOnScreenConfiguration =>
      null;

  @override
  // TODO: implement snapConfiguration
  FloatingHeaderSnapConfiguration get snapConfiguration => null;

  @override
  // TODO: implement stretchConfiguration
  OverScrollHeaderStretchConfiguration get stretchConfiguration => null;

  @override
  // TODO: implement vsync
  TickerProvider get vsync => null;
}
 

До сих пор я не нашел никакого решения для реализации этого, все еще просматривая веб-страницы.

Ответ №1:

Поскольку flutter имеет открытый исходный код, и у нас есть доступ к их встроенным кодам (недавно я глубоко изучил код каждого виджета, чтобы узнать, как работает каждая вещь ;-)), я обнаружил snap , что функциональность — это то, что я ищу из документации flutter . Итак, я изучил SliverAppBar и как в нем реализован snap. Просто скопировал то, что мне было нужно, и теперь все работает так, как ожидалось.

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

Комментарии:

1. вовсе нет, никаких глупых вопросов, которые бы интересовали, что вы сделали и чего вы добились от этого

Ответ №2:

Добавьте контроллер прокрутки в свой «Пользовательский вид прокрутки»

 ScrollController _scrollController;

Widget build(BuildContext context) {
_scrollController = ScrollController();
return Scaffold(
body: CustomScrollView( shrinkWrap: true, controller: _scrollController,
physics: BouncingScrollPhysics(),
slivers: <Widget>[
SliverAppBar(
pinned: false,
:
:
:
onPressed: () {// Scroll to top when on click => Expand 
_scrollController.animateTo(
_scrollController.position.minScrollExtent,
duration:Duration(milliseconds:1300),
curve: Curves.decelerate,);
 },

onPressed: () {// Scroll to bottom when on click => Collapse
scrollController.animateTo(
    scrollController.position.maxScrollExtent,
    duration: Duration(milliseconds: 1300),
    curve: Curves.decelerate,
  );
 },