Flutter实现仅搜索栏滚动时固定(非整个Sliver区域)
解决方案
你的问题出在把搜索栏放在了FlexibleSpaceBar的背景栈里,这会让搜索栏和图片绑定在一起,滚动时同步移动;同时固定的top:40在AppBar收缩时会导致搜索栏被遮挡,出现灰色栏。
要实现图片随滚动收起、搜索栏固定在顶部的效果,你需要把搜索栏从背景区域剥离,作为SliverAppBar的固定元素,而图片只放在FlexibleSpaceBar中。
修正后的代码示例
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: [ SliverAppBar( expandedHeight: 350, pinned: true, // 展开时背景透明,让图片完全显示 backgroundColor: Colors.transparent, // 搜索栏作为固定title,始终显示在顶部 title: _buildSearchBar(), flexibleSpace: FlexibleSpaceBar( background: Container( width: double.infinity, decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/login.jpg'), fit: BoxFit.cover, ), ), ), ), ), // 添加测试内容,方便查看滚动效果 SliverList( delegate: SliverChildBuilderDelegate( (context, index) => ListTile( title: Text('列表项 $index'), tileColor: index % 2 == 0 ? Colors.grey[100] : Colors.white, ), childCount: 50, ), ), ], ), ), ); } Widget _buildSearchBar() { return Material( color: Colors.transparent, child: TextField( decoration: InputDecoration( hintText: 'Search...', contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), filled: true, fillColor: Colors.white, suffixIcon: IconButton( icon: const Icon(Icons.search), onPressed: () {}, ), border: InputBorder.none, enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(30.0), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(30.0), ), ), ), ); } }
关键改动说明
- 将搜索栏从
FlexibleSpaceBar的Stack中移出,作为SliverAppBar的title属性,确保它在滚动时始终固定在顶部。 - 设置
SliverAppBar的backgroundColor为透明,避免展开时遮挡图片。 - 保留
pinned: true,确保AppBar收缩时固定顶部,搜索栏不会消失。
这样滚动页面时,图片会随着FlexibleSpaceBar收缩直至隐藏,而搜索栏会一直固定在屏幕顶部,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Ismail86
相关产品推荐
相关产品推荐

