Flutter动画:如何在DraggableScrollableSheet边框半径上进行更改?

3
在下面的代码中,我想要在DraggableScrollableSheet上动画更改边框半径,然后实现将其粘贴到屏幕顶部,例如AppBar,为此实现了更改边框半径的动画效果,但它不起作用,并出现以下错误:

错误:

构建_BottomBarControllerScope时抛出以下断言: 'package:flutter/src/animation/animations.dart': Failed assertion: line 376 pos 15: 'parent != null': is not true.

无论是框架本身中的错误还是我们应该提供更多信息以帮助您确定和修复根本原因的情况下,都应该通过在GitHub上提交bug报告来报告此断言:https://github.com/flutter/flutter/issues/new?template=BUG.md 当抛出异常时,这是堆栈: 2 new CurvedAnimation (package:flutter/src/animation/animations.dart:376:15) 3 _HomeState.initState (package:cheetah/screens/home/main/view/home.dart:45:7)

home.dart:45:7中的代码是:此处的CurvedAnimation是该代码的一部分。
borderRadius = BorderRadiusTween(
  begin: BorderRadius.circular(75.0),
  end: BorderRadius.circular(0.0),
).animate(
  CurvedAnimation(
    parent: _borderRadiusController,
    curve: Curves.ease,
  ),
);

my code:

class _HomeState extends State<Home> with TickerProviderStateMixin {
  AnimationController _draggableBottomSheetController;
  AnimationController _borderRadiusController;
  Animation<BorderRadius> borderRadius;
  Duration _duration = Duration(milliseconds: 500);
  Tween<Offset> _draggableBottomSheetTween = Tween(begin: Offset(0, 1), end: Offset(0, 0));

  @override
  void initState() {
    super.initState();
    _draggableBottomSheetController = AnimationController(vsync: this, duration: _duration);

    borderRadius = BorderRadiusTween(
      begin: BorderRadius.circular(75.0),
      end: BorderRadius.circular(0.0),
    ).animate(
      CurvedAnimation(
        parent: _borderRadiusController,
        curve: Curves.ease,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.rtl,
      child: AnimatedBuilder(
          animation: _borderRadiusController,
          builder: (BuildContext context, Widget widget){
            return Scaffold(
              backgroundColor: Theme.of(context).canvasColor,
              extendBody: true,
              primary: true,
              appBar: ApplicationToolbar(title: Strings.appName),
              resizeToAvoidBottomInset: false,
              resizeToAvoidBottomPadding: false,
              body: Container(
                color: applicationBackgroundColor,
                child: Stack(children: <Widget>[
                  Container(
                    width: double.infinity,
                    height: double.infinity,
                    child: PageView(
                      children: <Widget>[
                        FollowersFeedsPage(),
                      ],
                    ),
                  ),
                  SizedBox.expand(
                    child: SlideTransition(
                      position: _draggableBottomSheetTween.animate(_draggableBottomSheetController),
                      child: DraggableScrollableSheet(
                        builder: (BuildContext context, ScrollController scrollController) {
                          return ClipRRect(
                            borderRadius: borderRadius.value,
                            child: Container(
                              color: pageBackgroundColor,
                              child: ListView.builder(
                                controller: scrollController,
                                itemCount: 5,
                                itemBuilder: (BuildContext context, int index) {
                                  return ListTile(title: Text('Item $index'));
                                },
                              ),
                            ),
                          );
                        },
                      ),
                    ),
                  ),
                ]),
              ),
            );
          }
      ),
    );
  }
}
1个回答

3
最初的回答应该是这样的:

这应该是正确的做法。

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin {
  AnimationController _controller;
  BorderRadiusTween borderRadius;
  Duration _duration = Duration(milliseconds: 500);
  Tween<Offset> _tween = Tween(begin: Offset(0, 1), end: Offset(0, 0));
  double _height, min = 0.1, initial = 0.3, max = 0.7;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this, duration: _duration);
    borderRadius = BorderRadiusTween(
      begin: BorderRadius.circular(75.0),
      end: BorderRadius.circular(0.0),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: GestureDetector(
        child: FloatingActionButton(
          child: AnimatedIcon(icon: AnimatedIcons.menu_close, progress: _controller),
          elevation: 5,
          backgroundColor: Colors.deepOrange,
          foregroundColor: Colors.white,
          onPressed: () async {
            if (_controller.isDismissed)
              _controller.forward();
            else if (_controller.isCompleted) _controller.reverse();
          },
        ),
      ),
      body: SizedBox.expand(
        child: Stack(
          children: <Widget>[
            FlutterLogo(size: 500),
            SizedBox.expand(
              child: SlideTransition(
                position: _tween.animate(_controller),
                child: DraggableScrollableSheet(
                  minChildSize: min, // 0.1 times of available height, sheet can't go below this on dragging
                  maxChildSize: max, // 0.7 times of available height, sheet can't go above this on dragging
                  initialChildSize: initial, // 0.1 times of available height, sheet start at this size when opened for first time
                  builder: (BuildContext context, ScrollController controller) {
                    return AnimatedBuilder(
                      animation: controller,
                      builder: (context, child) {
                        return ClipRRect(
                         borderRadius: borderRadius.evaluate(CurvedAnimation(parent: _controller, curve: Curves.ease)),
                          child: Container(
                            height: 500.0,
                            color: Colors.blue[800],
                            child: ListView.builder(
                              controller: controller,
                              itemCount: 5,
                              itemBuilder: (BuildContext context, int index) {
                                return ListTile(title: Text('Item $index'));
                              },
                            ),
                          ),
                        );
                      },
                    );
                  },
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接