有什么办法可以在 flutter 中使用像 sliverappbar 这样的容器吗?

is there any way to use a container like sliverappbar in flutter?

前两天学习了flutter中sliver widget的使用,正在把玩中增长技能。我正在构建一种虚构的项目,在那里我遇到了一个问题。

让我们想想,我的 body 的 x 小部件下的容器中有 15 个容器允许它们滚动 vertically.Now,我的 objective 在这里,当我滚动时,我希望当 5 号容器到达顶部时,5 号容器会像 appbar 或 sliver appbar 一样卡在那里,其他容器会在其下方滚动。

这里我在 CustomScrollView 小部件下使用 sliver 和 SliverFixedExtentList 来了解我的 objective,如果有任何其他没有 slivers 的选项,请随时与我分享。提前致谢:)

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: CustomScrollView(
          slivers: <Widget>[
            SliverAppBar(
                actions: <Widget>[
                  Icon(
                    Icons.camera_front,
                    size: 40,
                  )
                ],
                title: Text("Sliver Example"),
                leading: Icon(Icons.menu),
                backgroundColor: Colors.green,
                expandedHeight: 100.0,
                floating: true,
                pinned: true),
            SliverFixedExtentList(
              itemExtent: 75,
              delegate: SliverChildListDelegate([
                Container(
                  color: Colors.blue,
                  child: Text("1"),
                ),
                Container(
                  color: Colors.pink,
                  child: Text("2"),
                ),
                Container(
                  color: Colors.yellow,
                  child: Text("3"),
                ),
                Container(
                  color: Colors.red,
                  child: Text("4"),
                ),
                Container(
                  color: Colors.black,
                  child: Text(
                    "Desired Appbar Conainer  number 5, which will stuck\n there instead of the sliverappbar sliver example when it reached to the top ",
                    style: TextStyle(color: Colors.white),
                  ),
                ),
                Container(
                  color: Colors.amber,
                  child: Text("6"),
                ),
                Container(
                  color: Colors.blue,
                  child: Text("7"),
                ),
                Container(
                  color: Colors.yellow,
                  child: Text("8"),
                ),
                Container(
                  color: Colors.blue,
                  child: Text("9"),
                ),
                Container(
                  color: Colors.pink,
                  child: Text("10"),
                ),
                Container(
                  color: Colors.blue,
                  child: Text("11"),
                ),
                Container(
                  color: Colors.yellow,
                  child: Text("12"),
                ),
                Container(
                  color: Colors.blue,
                  child: Text("13"),
                ),
                Container(
                  color: Colors.purpleAccent,
                  child: Text("14"),
                ),
                Container(
                  color: Colors.white,
                  child: Text("15"),
                ),
              ]),
            ),
          ],
        ),
      ),
    );
  }
}

你的想法仍然可行,只需要稍微调整一下,而不是使用 SliverFixedExtentList,你可以使用这个,flutter_sticky_header,它提供了粘性条子列表 header,对于你的情况,你可以只需设置一个 header:

import 'package:flutter/material.dart';
import 'package:flutter_sticky_header/flutter_sticky_header.dart';

import '../common.dart';

class ListExample extends StatelessWidget {
  const ListExample({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      slivers: [
        //SliverAppBar(),
        //SliverList(),
        _StickyHeaderList(index: 2),
        //SliverList(),
      ],
    );
  }
}

class _StickyHeaderList extends StatelessWidget {
  const _StickyHeaderList({
    Key key,
    this.index,
  }) : super(key: key);

  final int index;

  @override
  Widget build(BuildContext context) {
    return SliverStickyHeader(
      header: Header(index: index),
      sliver: SliverList(
        delegate: SliverChildBuilderDelegate(
          (context, i) => ListTile(
            leading: CircleAvatar(
              child: Text('$index'),
            ),
            title: Text('List tile #$i'),
          ),
          childCount: 6,
        ),
      ),
    );
  }
}

我似乎找到了这个 problem.The 答案的有效解决方案是基于 =>

这是我解决问题的代码-

import 'package:flutter/material.dart';
import 'dart:math' as math;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  SliverPersistentHeader makeHeader(String headerText) {
    return SliverPersistentHeader(
      pinned: true,
      delegate: _SliverAppBarDelegate(
        minHeight: 75.0,
        maxHeight: 75.0,
        child: Container(
          color: Colors.black,
          child: Center(
            child: Text(
              headerText,
              style: TextStyle(color: Colors.white),
            ),
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: CustomScrollView(
          slivers: <Widget>[
            SliverFixedExtentList(
              itemExtent: 75,
              delegate: SliverChildListDelegate([
                Container(
                  color: Colors.blue,
                  child: Text("1"),
                ),
                Container(
                  color: Colors.pink,
                  child: Text("2"),
                ),
                Container(
                  color: Colors.yellow,
                  child: Text("3"),
                ),
                Container(
                  color: Colors.red,
                  child: Text("4"),
                ),
              ]),
            ),
            makeHeader("Container Number 5"),
            SliverFixedExtentList(
              itemExtent: 75,
              delegate: SliverChildListDelegate([
                Container(
                  color: Colors.amber,
                  child: Text("6"),
                ),
                Container(
                  color: Colors.blue,
                  child: Text("7"),
                ),
                Container(
                  color: Colors.yellow,
                  child: Text("8"),
                ),
                Container(
                  color: Colors.blue,
                  child: Text("9"),
                ),
                Container(
                  color: Colors.pink,
                  child: Text("10"),
                ),
                Container(
                  color: Colors.blue,
                  child: Text("11"),
                ),
                Container(
                  color: Colors.yellow,
                  child: Text("12"),
                ),
                Container(
                  color: Colors.blue,
                  child: Text("13"),
                ),
                Container(
                  color: Colors.purpleAccent,
                  child: Text("14"),
                ),
                Container(
                  color: Colors.white,
                  child: Text("15"),
                ),
                Container(
                  color: Colors.yellow,
                  child: Text("12"),
                ),
                Container(
                  color: Colors.blue,
                  child: Text("13"),
                ),
                Container(
                  color: Colors.purpleAccent,
                  child: Text("14"),
                ),
                Container(
                  color: Colors.white,
                  child: Text("15"),
                ),
                Container(
                  color: Colors.yellow,
                  child: Text("12"),
                ),
                Container(
                  color: Colors.blue,
                  child: Text("13"),
                ),
                Container(
                  color: Colors.purpleAccent,
                  child: Text("14"),
                ),
                Container(
                  color: Colors.white,
                  child: Text("15"),
                ),
                Container(
                  color: Colors.yellow,
                  child: Text("12"),
                ),
                Container(
                  color: Colors.blue,
                  child: Text("13"),
                ),
                Container(
                  color: Colors.purpleAccent,
                  child: Text("14"),
                ),
                Container(
                  color: Colors.white,
                  child: Text("15"),
                ),
              ]),
            ),
          ],
        ),
      ),
    );
  }
}

class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
  _SliverAppBarDelegate({
    @required this.minHeight,
    @required this.maxHeight,
    @required this.child,
  });

  final double minHeight;
  final double maxHeight;
  final Widget child;

  @override
  double get minExtent => minHeight;

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

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

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

希望这对像我这样的人有帮助:)