首页 > 解决方案 > 没有内容在其下滚动时如何禁用AppBar阴影

问题描述

在 app_bar.dart 文件中提到,elevation控制应用栏下方阴影的大小,默认情况下,如果在 AppBar 下没有滚动内容,则不会绘制阴影。

这是我的代码:

Scaffold(
  appBar: AppBar(
    brightness: Brightness.light,
    backgroundColor: Colors.grey[50],
    leading: IconButton(
      icon: Icon(Icons.menu, color: Colors.blue),
      tooltip: 'Navigation menu',
      onPressed: null,
    ),
    actions: <Widget>[
      IconButton(
        icon: Icon(Icons.search, color: Colors.blue,),
        tooltip: 'Search',
        onPressed: null,
      ),
    ],
  ),
  body: listView,
);



在我的情况下,阴影总是被画出来!有没有办法解决这个问题或者我做错了什么?
谢谢

标签: flutter

解决方案


Diego Velasquez有一篇很棒的文章

基本上你想要的是将一个可滚动的列表视图和一个应用栏与其elevation值连接起来。当可滚动的位置位于“顶部”时 - 将高度值设置为 0,否则设置为默认值 (4)。使用小部件很容易做到ScrollController()

//empty_space is a distance of empty padding, only after scrolling through it the content starts getting under the app bar. 
static const double EMPTY_SPACE = 10.0;
ScrollController _controller;
bool isScrolledToTop = true;

@override
  void initState() {
    _controller = ScrollController();
    _controller.addListener(_scrollListener);
    super.initState();
  }

  _scrollListener() {
    if (_scrollController.offset <= _scrollController.position.minScrollExtent &&
        !_scrollController.position.outOfRange) {
      //call setState only when values are about to change
      if(!isScrolledToTop) {
        setState(() {
          //reach the top
          isScrolledToTop = true;
        });
      }

    }else{
      //call setState only when values are about to change
      if(_scrollController.offset > EMPTY_SPACE && isScrolledToTop) {
        setState(() {
          //not the top
          isScrolledToTop = false;
        });
      }
    }
  }

 @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
}

现在将控制器添加到您的列表视图中,它应该看起来像这样:

    ListView.builder(
              controller: _scrollController,
              itemCount: 30,
              itemBuilder: (context, index) {
                return ListTile(title: Text("Index : $index"));
              },
            )

最后一步是根据isScrolledToTop标志显示/隐藏应用栏的阴影:

appBar: AppBar(
      elevation: isScrolledToTop ? 0 : 4,
      ...,)

重要提示:我强烈建议您将 AppBar 创建为具有自己的 build() 方法 ( MyAppBar extends StatefulWidget implements PreferredSizeWidget) 和 move_scrollListener()方法的独立小部件。

由于该setState(){}方法强制在调用它的位置重建小部件,因此无论是重建整个 Page(包括主列表视图及其所有项目等)还是仅重建一个 AppBar 小部件,这都很重要。后者要便宜得多。

如果您需要更多详细信息,请联系我。干杯!


推荐阅读