Это решение, чтобы зафиксировать панель поиска и предотвратить ее сжатие:
Вы можете использовать два SilverAppBar
s, один для фонового изображения и один для поиска бар. Первый SilverAppBar
не имеет названия и отметки и не закреплен. Второй SilverAppBar
закреплен и имеет высоту, а его заголовок - SearchBar
.
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxScrolled) {
return <Widget>[
createSilverAppBar1(),
createSilverAppBar2()
];
},
body: ListView.builder(
itemCount: itemList.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(itemList[index]),
),
);
})),
);
}
SliverAppBar createSilverAppBar1() {
return SliverAppBar(
backgroundColor: Colors.redAccent,
expandedHeight: 300,
floating: false,
elevation: 0,
flexibleSpace: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return FlexibleSpaceBar(
collapseMode: CollapseMode.parallax,
background: Container(
color: Colors.white,
child: Image.asset(
'assets/mainBackImage.jpg',
fit: BoxFit.cover,
),
),
);
}),
);
}
SliverAppBar createSilverAppBar2() {
return SliverAppBar(
backgroundColor: Colors.redAccent,
pinned: true,
title: Container(
margin: EdgeInsets.symmetric(horizontal: 10),
height: 40,
decoration: BoxDecoration(
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.grey.withOpacity(0.6),
offset: const Offset(1.1, 1.1),
blurRadius: 5.0),
],
),
child: CupertinoTextField(
controller: _filter,
keyboardType: TextInputType.text,
placeholder: 'Search',
placeholderStyle: TextStyle(
color: Color(0xffC4C6CC),
fontSize: 14.0,
fontFamily: 'Brutal',
),
prefix: Padding(
padding: const EdgeInsets.fromLTRB(5.0, 5.0, 0.0, 5.0),
child: Icon(
Icons.search,
size: 18,
color: Colors.black,
),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Colors.white,
),
),
),
);
}
Результат:
This is a solution to make a layout based on gif-изображение 1 :
Используя Stack
, вы можете расположить панель поиска поверх фона. Смещение панели поиска будет expandedHeight - shrinkOffset - 20
, поскольку оно должно зависеть от того, насколько уменьшена панель приложения, и от общей высоты панели приложения, когда она не уменьшена. Число 20 составляет половину высоты строки поиска, и из нее вычитается, чтобы строка поиска перемещалась вверх на половину своей высоты.
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxScrolled) {
return <Widget>[
SliverPersistentHeader(
delegate: MySliverAppBar(expandedHeight: 200, filter: _filter),
pinned: true,
),
];
},
body: ListView.builder(
itemCount: itemList.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(itemList[index]),
),
);
})),
);
}
class MySliverAppBar extends SliverPersistentHeaderDelegate {
final double expandedHeight;
final TextEditingController filter;
MySliverAppBar({@required this.expandedHeight, @required this.filter});
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
var searchBarOffset = expandedHeight - shrinkOffset - 20;
return Stack(
fit: StackFit.expand,
overflow: Overflow.visible,
children: [
Container(
child: Image.network(
'assets/mainBackImage.jpg',
fit: BoxFit.cover,
),
),
(shrinkOffset < expandedHeight - 20) ? Positioned(
top: searchBarOffset,
left: MediaQuery.of(context).size.width / 4,
child: Card(
elevation: 10,
child: SizedBox(
height: 40,
width: MediaQuery.of(context).size.width / 2,
child: CupertinoTextField(
controller: filter,
keyboardType: TextInputType.text,
placeholder: 'Search',
placeholderStyle: TextStyle(
color: Color(0xffC4C6CC),
fontSize: 14.0,
fontFamily: 'Brutal',
),
prefix: Padding(
padding: const EdgeInsets.fromLTRB(5.0, 5.0, 0.0, 5.0),
child: Icon(
Icons.search,
size: 18,
color: Colors.black,
),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Colors.white,
),
),
),
),
) : Container(
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width / 4,
vertical: (kToolbarHeight - 40) / 4
),
child: Card(
elevation: 10,
child: CupertinoTextField(
controller: filter,
keyboardType: TextInputType.text,
placeholder: 'Search',
placeholderStyle: TextStyle(
color: Color(0xffC4C6CC),
fontSize: 14.0,
fontFamily: 'Brutal',
),
prefix: Padding(
padding: const EdgeInsets.fromLTRB(5.0, 5.0, 0.0, 5.0),
child: Icon(
Icons.search,
size: 18,
color: Colors.black,
),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Colors.white,
),
),
),
),
],
);
}
@override
double get maxExtent => expandedHeight;
@override
double get minExtent => kToolbarHeight;
@override
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true;
}
Результат:
res2