flutter 如何在AppBar阴影下没有内容滚动时禁用它

3j86kqsm  于 2023-01-14  发布在  Flutter
关注(0)|答案(3)|浏览(212)

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

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,
);

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

dpiehjr4

dpiehjr41#

迭戈·贝拉斯克斯写了一篇关于这个的文章。
基本上你需要的是用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),然后将_scrollListener()方法移到那里。

由于setState(){}方法强制在调用它的地方重新构建小部件,因此无论是重新构建整个Page(包括主列表视图及其所有项等)还是仅重建一个AppBar小部件都很重要,后者要便宜得多。
如果你需要更多的细节给我打电话。干杯!

w46czmvw

w46czmvw2#

实际上,SliverAppBar正是使用了这种行为,当内容没有滚动到它下面时,它没有阴影,如果你愿意,它甚至可以在你滚动内容时滚动离开。这里有一个视频解释了如何在Flutter应用中使用切片:https://www.youtube.com/watch?v=wN2lpqxkB4M
另外,如果您只是不希望AppBar有阴影,则可以将其elevation属性设置为0.0,如下所示:

AppBar(
    elevation: 0.0,
    title: Text("This is my title"),
),
jogvjijk

jogvjijk3#

要删除AppBar的标高,只需将elevation设置为0。如果要在内容滚动到AppBar下时保持标高,只需将scrolledUnderElevation设置为非零值。请参见docs

AppBar(
    elevation: 0,
    scrolledUnderElevation: 4,
)

相关问题