Flutter记录自学flutter点点滴滴

Flutter 学习之旅(二十八) 滑动渐变

2020-08-28  本文已影响0人  Tsm_2020

需要使用滑动渐变在前面一篇文章中已经有提到过,那就是必须使用 CustomScrollView ,
而滑动渐变又离不开appbar,而CustomScrollView 中又引入SliverAppBar 这个控件

  const SliverAppBar({
    Key key,
    this.leading,
    this.automaticallyImplyLeading = true,
    this.title,
    this.actions,
    this.flexibleSpace,
    this.bottom,
    this.elevation,
    this.shadowColor,
    this.forceElevated = false,
    this.backgroundColor,
    this.brightness,
    this.iconTheme,
    this.actionsIconTheme,
    this.textTheme,
    this.primary = true,
    this.centerTitle,
    this.excludeHeaderSemantics = false,
    this.titleSpacing = NavigationToolbar.kMiddleSpacing,
    this.collapsedHeight,
    this.expandedHeight,
    this.floating = false,
    this.pinned = false,
    this.snap = false,
    this.stretch = false,
    this.stretchTriggerOffset = 100.0,
    this.onStretchTrigger,
    this.shape,
    this.toolbarHeight = kToolbarHeight,
  })

这个里面很多属性在AppBar中都有说过,这里说一下剩下几个主要的属性

    /// 停止拖动是否 继续响应拖动事件
   snap: false,
   /// 下滑过程中是否优先展开头部折叠部分 ,
   floating: false,
   ///pinned(固定的)  控制隐藏和展示的   false 就是可以随列表滑出屏幕外  true 不可以
   pinned: true,
   onStretchTrigger: () {
       printString('onStretchTrigger');
         return;
    },
   expandedHeight: 200,///展开后的高度
  flexibleSpace: Widget ,///展开后的控件
image.png

再来说一下

这三个属性

floating: true, pinned: false, 时 的滑动表现

GIF 2020-8-27 15-59-06.gif

floating: false, pinned: true, 时 的滑动表现

GIF 2020-8-27 16-02-52.gif

floating 如果为true 在下滑过程中优先展开折叠的部分

pinned false 就是可以随列表滑出屏幕外 true 不可以

SliverToBoxAdapter

在CustomScrollView 中是能使用Sliver系的控件,如果在CustomScrollView 中想要嵌套其他非 Sliver 系就必须要使用SliverToBoxAdapter包装一下,

来一个综合的例子

这个例子中我添加了下拉刷新部分,发现这个刷新部分放在哪个位置,哪个位置就有刷新的功能

class _TsmCustomScrollViewState extends State<TsmCustomScrollViewPage> {
  @override
  Widget build(BuildContext context) {
    return Material(
      child: CustomScrollView(
        physics: BouncingScrollPhysics(),

        ///越界回弹效果
        slivers: [
          CupertinoSliverRefreshControl(
            refreshIndicatorExtent: 60,

            /// 刷新过程中悬浮高度
            refreshTriggerPullDistance: 100,

            ///触发刷新的距离
            /// 自定义布局
            builder: (context, buildRefreshindictor, pulledExtent,
                refreshTriggerPullDistance, refreshIndicatorExtent) {
              printString(
                  'pulledExtent : ${pulledExtent}   ,refreshTriggerPullDistance  : ${refreshTriggerPullDistance}    refreshIndicatorExtent:${refreshIndicatorExtent}');
              return Container(
                color: Colors.redAccent,
                height: 150,
                alignment: Alignment.center,
                child: AnimatedOpacity(
                    duration: Duration(milliseconds: 300),
                    //opacity: top == 80.0 ? 1.0 : 0.0,
                    opacity: 1.0,
                    child: Text(
                      RefreshIndicatorMode.done == buildRefreshindictor
                          ? '已拉动:${pulledExtent.round()}  松开刷新'
                          : '已拉动:${pulledExtent.round()}  下拉刷新',
                      style: TextStyle(fontSize: 12.0),
                    )),
              );
            },

            ///触发刷新回调
            onRefresh: () async {
              await Future.delayed(Duration(seconds: 3));
              printString('CupertinoSliverRefreshControl   onRefresh');
            },
          ),

          SliverAppBar(
            centerTitle: true,
            titleSpacing: 0,
            title: Text(
              'CustomScrollView',
              style: TextStyle(color: Colors.black87),
            ),

            /// 停止拖动是否 继续响应拖动事件
            snap: false,

            /// 下滑过程中是否优先展开头部折叠部分 ,
            floating: false,

            ///pinned(固定的)  控制隐藏和展示的   false 就是可以随列表滑出屏幕外  true 不可以
            pinned: true,
            backgroundColor: Colors.blueAccent,
            expandedHeight: 200,///展开后的高度
            flexibleSpace: LayoutBuilder(
              builder: (context, cons) {
                return FlexibleSpaceBar(
//              collapseMode: CollapseMode.pin,
                    background: Container(
                  decoration: BoxDecoration(
                    image: DecorationImage(
                        image: AssetImage('images/hor.jpg'), fit: BoxFit.fill),
                  ),
                  child: Column(
                    mainAxisSize: MainAxisSize.max,
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      Text(
                        '这个是头部',
                        style: TextStyle(color: Colors.pink),
                      ),
                      Text(
                        '这个是头部',
                        style: TextStyle(color: Colors.pink),
                      ),
                      Text(
                        '这个是头部',
                        style: TextStyle(color: Colors.pink),
                      ),
                      Text(
                        '这个是头部',
                        style: TextStyle(color: Colors.pink),
                      ),
                      Text(
                        '这个是头部',
                        style: TextStyle(color: Colors.pink),
                      ),
                    ],
                  ),
                ));
              },
            ),
          ),
//
          SliverPersistentHeader(
            floating: true,
            pinned: false,
            delegate: _SliverPersistenHeaderDelegate(
                minHeight: 50, maxHeight: 150, child: Text('1111')),
          ),
          SliverSafeArea(
            sliver: SliverList(
                delegate: SliverChildBuilderDelegate(
                    (context, index) => Container(
                          height: 50,
                          margin: const EdgeInsets.all(5),
                          decoration: BoxDecoration(
                            color: Colors.white,
                            border: Border.all(color: Colors.grey),
                            borderRadius: BorderRadius.all(Radius.circular(9)),
                          ),
                          child: Center(
                            child: Text(index.toString()),
                          ),
                        ),
                    childCount: 50)),
          )
        ],
      ),
    );
  }
}

class _SliverPersistenHeaderDelegate extends SliverPersistentHeaderDelegate {
  double maxHeight;
  double minHeight;
  Widget child;

  _SliverPersistenHeaderDelegate({this.maxHeight, this.minHeight, this.child});

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return SizedBox.expand(
      child: child,
    );
  }

  @override
  double get maxExtent => max<double>(minHeight, maxHeight);

  @override
  // TODO: implement minExtent
  double get minExtent => min<double>(minHeight, maxHeight);

  @override
  bool shouldRebuild(_SliverPersistenHeaderDelegate oldDelegate) {
    return maxHeight != oldDelegate.maxHeight ||
        minHeight != oldDelegate.minHeight ||
        child != oldDelegate.child;
  }
}


我学习flutter的整个过程都记录在里面了
https://www.jianshu.com/c/36554cb4c804

最后附上demo 地址

https://github.com/tsm19911014/tsm_flutter

上一篇下一篇

猜你喜欢

热点阅读