首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DraggableScrollableNotification + snap + setState

DraggableScrollableNotification + snap + setState
EN

Stack Overflow用户
提问于 2022-08-02 01:33:54
回答 2查看 114关注 0票数 1

在DraggableScrollableNotification事件中,使用snap属性设置为true的snap+ onNotification会导致DraggableScrollableSheet不能正常工作。

代码语言:javascript
复制
void _update(double extent) {
    double _scrollPosition = extent;

    setState(() {
      newBorderRadiusSize =
          ((minChildSize * defaulBorderRadiusSize) / _scrollPosition);

      newHorizontalPadding =
          ((horizontalPadding * minChildSize) / _scrollPosition);
      newVerticalPadding = ((verticalPadding * minChildSize) / _scrollPosition);

      //does not look smooth :/
      if (extent >= maxChildSize) {
        newBorderRadiusSize = 0;
        newHorizontalPadding = 0;
        newVerticalPadding = 0;
      }
    });
  }

return NotificationListener<DraggableScrollableNotification>(
      onNotification: (notification) {
        _update(notification.extent);
        return true;
      },
      child: Positioned.fill(
        left: newHorizontalPadding,
        right: newHorizontalPadding,
        bottom: newVerticalPadding,
        child: DraggableScrollableSheet(
          maxChildSize: maxChildSize,
          minChildSize: minChildSize,
          initialChildSize: minChildSize,
          controller: _draggableScrollableController,
          snap: true,
          builder: ((context, scrollController) {
            
            return ClipRRect(
              borderRadius: BorderRadius.circular(newBorderRadiusSize),
              child: Container(
                decoration: BoxDecoration(color: AppColors.secondary),
                padding: EdgeInsets.all(16),
                child: SingleChildScrollView(
                  controller: scrollController,
                  child: Column(
                    children: [
                      TaxiDragger(),
                      Divider(color: Colors.transparent),
                      TaxiNotification(),
                    ],
                  ),
                ),
              ),
            );
          }),
        ),
      ),
    );

如果我删除了snap属性(默认设置为false),那么所有东西都能很好地工作,但是我想要有snap属性。

EN

回答 2

Stack Overflow用户

发布于 2022-08-12 09:04:07

我发现了一些非常有趣的东西:如果您修改onNotification函数中的状态变量而不实际使用setState --它的工作方式与预期完全相同

代码语言:javascript
复制
  class _MyStatefullWidgetState extends State<MyStatefullWidget> {
      bool shouldDisplaySomething = false;
    
      @override
      Widget build(BuildContext context) => NotificationListener<DraggableScrollableNotification>(
          onNotification: (DraggableScrollableNotification event) {
              // doing this in setState breaks DraggableScrollableSheet behaviour
              shouldDisplaySomething = event.extent > 0.9;
              return false;
          },
          child: DraggableScrollableSheet(
              ...

似乎DraggableScrollableSheet在拖动时会导致子程序重登,并且新的呈现周期将恢复更新的状态,即使没有显式地使用setState

从onNotification函数返回false可能也很重要,因为bool决定通知冒泡如果返回true,冒泡将被停止,这反过来会破坏默认的预期行为。

票数 1
EN

Stack Overflow用户

发布于 2022-08-02 02:21:03

在回答我自己的问题时,它似乎是一个带有颤振的bug,在任何情况下,我都能够存档我正在寻找的东西,而不是将定位动画化,而是在DraggableScrollable中动画容器。

代码语言:javascript
复制
return Positioned.fill(
      child: NotificationListener<DraggableScrollableNotification>(
        onNotification: (notification) {
          _scrolledSize = notification.extent;

          newBorderRadiusSize =
              ((minChildSize * defaulBorderRadiusSize) / _scrolledSize);

          newHorizontalPadding =
              ((horizontalPadding * minChildSize) / _scrolledSize);
          newVerticalPadding =
              ((verticalPadding * minChildSize) / _scrolledSize);

          //does not look smooth :/
          if (_scrolledSize >= maxChildSize) {
            newBorderRadiusSize = 0;
            newHorizontalPadding = 0;
            newVerticalPadding = 0;
          }

          return true;
        },
        child: DraggableScrollableSheet(
          maxChildSize: maxChildSize,
          minChildSize: minChildSize,
          initialChildSize: minChildSize,
          controller: _draggableScrollableController,
          snap: true,
          builder: ((context, scrollController) {
            return Container(
              decoration: BoxDecoration(
                  color: AppColors.secondary,
                  borderRadius: BorderRadius.circular(newBorderRadiusSize)),
              //width: newBorderRadiusSize,
              margin: EdgeInsets.only(
                left: newHorizontalPadding,
                right: newHorizontalPadding,
                bottom: newVerticalPadding,
              ),
              padding: EdgeInsets.all(16),
              child: CustomScrollView(
                physics: ClampingScrollPhysics(),
                controller: scrollController,
                slivers: [
                  SliverList(
                    delegate: SliverChildBuilderDelegate(
                      (context, i) => Column(
                        children: [
                          Text(newHorizontalPadding.toString(),
                              style: TextStyle(fontSize: newHorizontalPadding)),
                          TaxiDragger(),
                          Divider(color: Colors.transparent),
                          TaxiNotification(),
                        ],
                      ),
                      childCount: 20,
                    ),
                  )
                ],
              ),
            );
          }),
        ),
      ),
    );

我希望这对其他人有帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73201130

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档