颤动:在检测到滚动时隐藏并显示应用栏

问题描述 投票:0回答:1

我在应用栏动画方面遇到麻烦,我在我的应用中使用SilverAppBar。所以,问题是当我在我的列表中间并向上滚动时,应用栏不会出现,但只有当滚动到达项目列表的顶部时才会出现。我已经测试了snap参数并给它true,但不是我期望的结果。我有关于为此创建自定义动画的想法,但我在Flutter中没有太多经验,如果有一种方法可以添加参数,或者另一个小部件可以适用于我的情况,那就太棒了。

我正在使用的演示的实际代码:

  Widget _search() => Container(
        color: Colors.grey[400],
        child: SafeArea(
            child: Container(
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: TextField(
              enabled: false,
              style: TextStyle(fontSize: 16, color: Colors.white),
              decoration: InputDecoration(
                prefix: SizedBox(width: 12),
                hintText: "Search",
                contentPadding:
                    EdgeInsets.symmetric(horizontal: 32.0, vertical: 14.0),
                border: InputBorder.none,
              ),
            ),
          ),
        )),
      );

  Container _buildBody() {
    return Container(
        child: new GridView.count(
      crossAxisCount: 2,
      children: List.generate(100, (index) {
        return Center(
          child: Text(
            'Item $index',
            style: Theme.of(context).textTheme.headline,
          ),
        );
      }),
    ));
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        resizeToAvoidBottomPadding: false,
        body: new NestedScrollView(
            headerSliverBuilder:
                (BuildContext context, bool innerBoxIsScrolled) {
              return <Widget>[
                new SliverAppBar(
                  title: Text("Demo",
                      style: TextStyle(
                        color: Colors.white,
                      )),
                  pinned: false,
                  floating: true,
                  forceElevated: innerBoxIsScrolled,
                ),
              ];
            },
            body: new Column(children: <Widget>[
              _search(),
              new Expanded(child: _buildBody())
            ])));
  }

我现在的结果:Image 1

truesnap参数后得到的结果:Image 2

很多应用程序,如WhatsApp,Facebook,LinkedIn ......都有这个动画应用程序栏。为了更详细地解释我对这个动画应用栏的期望,我添加了一个Google Play商店示例,展示了想要的动画:Play Store example

animation scroll flutter appbar
1个回答
0
投票

要使此功能起作用,您需要使用CustomScrollView小部件而不是NestedScrollViewGoogle Documentation

这是一个工作示例:

class MyHomeState extends State<MyHome> {
@override
Widget build(BuildContext context) {
  return Scaffold(
    body: CustomScrollView(
      slivers: <Widget>[
        const SliverAppBar(
          pinned: false,
          snap: false,
          floating: true,
          flexibleSpace: FlexibleSpaceBar(
            title: Text('Demo'),
          ),
        ),
        SliverGrid(
          gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
            maxCrossAxisExtent: 200.0,
            mainAxisSpacing: 10.0,
            crossAxisSpacing: 10.0,
            childAspectRatio: 4.0,
          ),
          delegate: SliverChildBuilderDelegate(
            (BuildContext context, int index) {
              return Container(
                alignment: Alignment.center,
                color: Colors.teal[100 * (index % 9)],
                child: Text('grid item $index'),
              );
            },
            childCount: 50,
          ),
        ),
      ],
    )
  );
}
}

Example of this running here


0
投票

我使用刷新指示器在CustomScrollView和SliverAppbar上遇到了类似的问题,我最终创建了自己的自定义应用栏。

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

    class HomeView extends StatefulWidget {
      @override
      HomeState createState() => HomeState();
    }

    class HomeState extends State<HomeView> with SingleTickerProviderStateMixin {
      bool _isAppbar = true;
      ScrollController _scrollController = new ScrollController();

      @override
      void initState() {
        super.initState();
        _scrollController.addListener(() {
          if (_scrollController.position.userScrollDirection ==
              ScrollDirection.reverse) {
            appBarStatus(false);
          }
          if (_scrollController.position.userScrollDirection ==
              ScrollDirection.forward) {
            appBarStatus(true);
          }
        });
      }

      void appBarStatus(bool status) {
        setState(() {
          _isAppbar = status;
        });
      }

      @override
      Widget build(BuildContext context) {
        return SafeArea(
          child: Scaffold(
            appBar: PreferredSize(
              preferredSize: Size.fromHeight(kToolbarHeight),
              child: AnimatedContainer(
                height: _isAppbar ? 55.0 : 0.0,
                duration: Duration(milliseconds: 200),
                child: CustomAppBar(),
              ),
            ),
            body: ListView.builder(
              controller: _scrollController,
              itemCount: 20,
              itemBuilder: (BuildContext context, int index) {
                return container();
              },
            ),
          ),
        );
      }
    }

    Widget container() {
      return Container(
        height: 80.0,
        color: Colors.pink,
        margin: EdgeInsets.all(8.0),
        width: 100,
        child: Center(
            child: Text(
          'Container',
          style: TextStyle(
            fontSize: 18.0,
          ),
        )),
      );
    }

    class CustomAppBar extends StatefulWidget {
      @override
      AppBarView createState() => new AppBarView();
    }

    class AppBarView extends State<CustomAppBar> {
      @override
      Widget build(BuildContext context) {
        return AppBar(
          backgroundColor: Colors.white,
          leading: InkWell(
            onTap: () => {},
            child: new Padding(
              padding: const EdgeInsets.all(8.0),
              child: CircleAvatar(
                backgroundColor: Colors.white,
                child: ClipOval(
                  child: Image.network(
                      'https://images.squarespace-cdn.com/content/5aee389b3c3a531e6245ae76/1530965251082-9L40PL9QH6PATNQ93LUK/linkedinPortraits_DwayneBrown08.jpg?format=1000w&content-type=image%2Fjpeg'),
                ),
              ),
            ),
          ),
          actions: <Widget>[
            IconButton(
              alignment: Alignment.centerLeft,
              icon: Icon(
                Icons.search,
                color: Colors.black,
              ),
              onPressed: () {},
            ),
          ],
          title: Container(
            alignment: Alignment.centerLeft,
            child: Text("Custom Appbar", style: TextStyle(color: Colors.black),)
          ),
        );
      }
    }
© www.soinside.com 2019 - 2024. All rights reserved.