【问题标题】:Custom FlexibleSpaceBar Widget自定义 FlexibleSpaceBar 小部件
【发布时间】:2020-11-23 15:51:15
【问题描述】:

我希望标题在图片下方,并与图片折叠......

我的成就

home: Scaffold(
  body: CustomScrollView(
    slivers: <Widget>[
      SliverAppBar(

       expandedHeight: 220.0,
        floating: true,
        pinned: true,
        snap: true,
        elevation: 50,
        backgroundColor: Colors.pink,
        flexibleSpace: FlexibleSpaceBar(
            centerTitle: true,
            title: Text('Title',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 16.0,
                )),
            background: Image.network(
              'https://images.pexels.com/photos/443356/pexels-photo-443356.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
              fit: BoxFit.cover,
            )
        ),
      ),
      new SliverList(
          delegate: new SliverChildListDelegate(_buildList(50))
      ),
    ],
  ),

我想要什么

感谢您的帮助

【问题讨论】:

    标签: flutter flutter-layout flutter-sliver


    【解决方案1】:

    希望我的回答不会太晚,我的回答会对你有所帮助。

    如果您检查flexibleSpace 参数类型,您会注意到它接受任何Widget

    因此您可以创建自己的小部件,并将标题从 SliverAppBar 移动到您的 NewFlexibleSpaceWidget

    另外你可以去查看FlexibleSpaceBar,看看 Flutter 开发团队是如何实现它的。

    当我们缩小或扩展SliverAppBarWidget 时,它会改变FlexibleSpaceBoxConstraints,因此这意味着我们可以通过使用LayoutBuilder 来捕捉新的高度,这将为我们提供当前的BoxConstraints。我们可以使用它们来绘制动画。

    import 'dart:math' as math;
    
    import 'package:flutter/material.dart';
    import 'package:flutter/rendering.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: Scaffold(
            body: SafeArea(
              child: MyHomePage(),
            ),
          ),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      ScrollController controller = ScrollController();
      @override
      Widget build(BuildContext context) {
        return CustomScrollView(
          physics: ClampingScrollPhysics(),
          controller: controller,
          slivers: [
            SliverAppBar(
              expandedHeight: 220.0,
              floating: true,
              pinned: true,
              snap: true,
              elevation: 50,
              backgroundColor: Colors.pink,
              leading: IconButton(
                icon: Icon(Icons.filter_1),
                onPressed: () {},
              ),
              flexibleSpace: _MyAppSpace(),
            ),
            SliverList(
              delegate: SliverChildListDelegate(
                List.generate(
                  200,
                  (index) => Card(
                    child: Padding(
                      padding: EdgeInsets.all(10),
                      child: Text('text $index'),
                    ),
                  ),
                ),
              ),
            )
          ],
        );
      }
    }
    
    class _MyAppSpace extends StatelessWidget {
      const _MyAppSpace({Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return LayoutBuilder(
          builder: (context, c) {
            final settings = context
                .dependOnInheritedWidgetOfExactType<FlexibleSpaceBarSettings>();
            final deltaExtent = settings.maxExtent - settings.minExtent;
            final t =
                (1.0 - (settings.currentExtent - settings.minExtent) / deltaExtent)
                    .clamp(0.0, 1.0) as double;
            final fadeStart = math.max(0.0, 1.0 - kToolbarHeight / deltaExtent);
            const fadeEnd = 1.0;
            final opacity = 1.0 - Interval(fadeStart, fadeEnd).transform(t);
    
            return Opacity(
              opacity: opacity,
              child: Column(
                children: [
                  Flexible(
                    child: Container(
                      width: double.infinity,
                      child: Image.network(
                        'https://images.pexels.com/photos/443356/pexels-photo-443356.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
                        fit: BoxFit.cover,
                      ),
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(
                      'Title',
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 26.0,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                ],
              ),
            );
          },
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-27
      • 2012-08-06
      • 2011-11-05
      • 2020-10-15
      • 2016-05-17
      • 2019-03-28
      • 2019-04-01
      • 2018-08-17
      相关资源
      最近更新 更多