一統天下 flutter - widget Sliver: SliverPersistentHeader - 自定義可展開/收縮的標題欄

源碼 https://github.com/webabcd/flutter_demo
作者 webabcd

一統天下 flutter - widget Sliver: SliverPersistentHeader - 自定義可展開/收縮的標題欄

示例如下:

lib\widget\sliver\sliver_persistent_header.dart

/*
 * SliverPersistentHeader - 自定義可展開/收縮的標題欄
 */

import 'dart:math';

import 'package:flutter/material.dart';

import '../../helper.dart';

class SliverPersistentHeaderDemo extends StatefulWidget {
  const SliverPersistentHeaderDemo({Key? key}) : super(key: key);

  @override
  _SliverPersistentHeaderDemoState createState() => _SliverPersistentHeaderDemoState();
}

class _SliverPersistentHeaderDemoState extends State<SliverPersistentHeaderDemo> {

  final _random = Random();
  Color _getRandomColor() {
    return Color.fromARGB(255, _random.nextInt(256), _random.nextInt(256), _random.nextInt(256),);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: CustomScrollView(
        slivers: [
          /// 使用自定義可展開/收縮的標題欄
          SliverPersistentHeader(
            delegate: _MySliverPersistentHeaderDelegate(),
            /// true - 下拉滾動時,即使當前 CustomScrollView 不在頂部,SliverPersistentHeader 也會向下展開
            /// false - 下拉滾動時,只有當前 CustomScrollView 在頂部時,SliverPersistentHeader 纔會向下展開
            floating: true,
            /// true - SliverPersistentHeader 在完全收縮狀態時,其高度爲 SliverPersistentHeaderDelegate 的 minExtent
            /// false - SliverPersistentHeader 在完全收縮狀態時,會徹底隱藏
            pinned: true,
          ),

          SliverList(
            delegate: SliverChildBuilderDelegate((context, index) =>
                Container(color: _getRandomColor(), height: 150,),
              childCount: 20,
            ),
          ),
        ],
      ),
    );
  }
}

/// 自定義可展開/收縮的標題欄的具體邏輯
class _MySliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate {

  final double _minExtent = 100;
  final double _maxExtent = 300;

  /// 當展開/收縮的大小發生變化時就會執行到這裏
  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    /// shrinkOffset - 高度的偏移量(0 - maxExtent 之間)
    ///   完全展開狀態,此值爲 0
    ///   完全收縮狀態,此值爲 maxExtent
    log('shrinkOffset:$shrinkOffset, overlapsContent:$overlapsContent');
    return Container(
      alignment: Alignment.center,
      decoration: const BoxDecoration(
        image: DecorationImage(
          image: AssetImage("assets/son.jpg"),
          fit: BoxFit.cover,
        ),
      ),
    );
  }

  /// 完全展開狀態的高度
  @override
  double get maxExtent => _maxExtent;

  /// 完全收縮狀態的高度
  @override
  double get minExtent => _minExtent;

  /// 是否需要重建(當 maxExtent 或 minExtent 發生變化時,應該返回 true)
  @override
  bool shouldRebuild(covariant _MySliverPersistentHeaderDelegate oldDelegate) {
    return false;
  }
}

源碼 https://github.com/webabcd/flutter_demo
作者 webabcd

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章