123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- import 'package:flutter/material.dart';
- import 'package:get/get.dart';
- import 'package:ftrecruiter/comm/utils/log_utils.dart';
- import 'package:ftrecruiter/comm/widget/load_state_layout.dart';
- import 'package:ftrecruiter/comm/widget/my_load_image.dart';
- import 'package:ftrecruiter/modules/zdemo/page_four.dart';
- import 'package:ftrecruiter/modules/zdemo/page_one.dart';
- import 'package:ftrecruiter/modules/zdemo/page_three.dart';
- import 'package:ftrecruiter/modules/zdemo/page_two.dart';
- class DemoScroll1Page extends StatelessWidget {
- const DemoScroll1Page({Key? key}) : super(key: key);
- @override
- Widget build(BuildContext context) {
- final _tabs = <String>['猜你喜欢', '今日特价', '发现更多'];
- // 构建 tabBar
- return DefaultTabController(
- length: _tabs.length, // This is the number of tabs.
- child: Scaffold(
- body: NestedScrollView(
- headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
- return <Widget>[
- SliverOverlapAbsorber(
- handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
- sliver: SliverAppBar(
- title: const Text('商城'),
- floating: false,
- snap: false,
- elevation: 0.0,
- forceElevated: innerBoxIsScrolled,
- pinned: true,
- ),
- ),
- SliverToBoxAdapter(
- child: Container(
- alignment: Alignment.center,
- width: double.infinity,
- height: 191,
- child: MyLoadImage("https://i04piccdn.sogoucdn.com/a35bde4b5756167a",width: 340, height: 191),
- ),
- ),
- SliverPersistentHeader(
- pinned: true, // 固定在顶部
- delegate: SliverHeaderDelegate.fixedHeight( //固定高度
- height: 50,
- child: Container(
- color: Colors.pink,
- child: TabBar(
- tabs: _tabs.map((String name) => Tab(text: name)).toList(),
- ),
- ),
- ),
- ),
- ];
- },
- body: TabBarView(
- children: _tabs.map((String name) {
- return Builder(
- builder: (BuildContext context) {
- return CustomScrollView(
- key: PageStorageKey<String>(name),
- slivers: <Widget>[
- SliverOverlapInjector(
- handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
- ),
- SliverPadding(
- padding: const EdgeInsets.all(8.0),
- sliver: buildSliverList(50),
- ),
- ],
- );
- },
- );
- }).toList(),
- ),
- ),
- ),
- );
- }
- // 构建固定高度的SliverList,count为列表项属相
- Widget buildSliverList([int count = 5]) {
- return SliverFixedExtentList(
- itemExtent: 50,
- delegate: SliverChildBuilderDelegate(
- (context, index) {
- return ListTile(title: Text('$index'));
- },
- childCount: count,
- ),
- );
- }
- }
- typedef SliverHeaderBuilder = Widget Function(
- BuildContext context, double shrinkOffset, bool overlapsContent);
- class SliverHeaderDelegate extends SliverPersistentHeaderDelegate {
- // child 为 header
- SliverHeaderDelegate({
- required this.maxHeight,
- this.minHeight = 0,
- required Widget child,
- }) : builder = ((a, b, c) => child),
- assert(minHeight <= maxHeight && minHeight >= 0);
- //最大和最小高度相同
- SliverHeaderDelegate.fixedHeight({
- required double height,
- required Widget child,
- }) : builder = ((a, b, c) => child),
- maxHeight = height,
- minHeight = height;
- //需要自定义builder时使用
- SliverHeaderDelegate.builder({
- required this.maxHeight,
- this.minHeight = 0,
- required this.builder,
- });
- final double maxHeight;
- final double minHeight;
- final SliverHeaderBuilder builder;
- @override
- Widget build(
- BuildContext context,
- double shrinkOffset,
- bool overlapsContent,
- ) {
- Widget child = builder(context, shrinkOffset, overlapsContent);
- //测试代码:如果在调试模式,且子组件设置了key,则打印日志
- assert(() {
- if (child.key != null) {
- print('${child.key}: shrink: $shrinkOffset,overlaps:$overlapsContent');
- }
- return true;
- }());
- // 让 header 尽可能充满限制的空间;宽度为 Viewport 宽度,
- // 高度随着用户滑动在[minHeight,maxHeight]之间变化。
- return SizedBox.expand(child: child);
- }
- @override
- double get maxExtent => maxHeight;
- @override
- double get minExtent => minHeight;
- @override
- bool shouldRebuild(SliverHeaderDelegate old) {
- return old.maxExtent != maxExtent || old.minExtent != minExtent;
- }
- }
|