gpt4 book ai didi

flutter - Flutter 中具有搜索功能的 sliver 应用栏

转载 作者:行者123 更新时间:2023-12-03 02:43:54 47 4
gpt4 key购买 nike

希望你有美好的一天。我想在下面实现这样的事情 => gif image 1
谁的 gif 不清楚。这是来自名为 Yelp 的应用程序的屏幕截图.它是具有扩展和折叠功能的银色应用栏。当它折叠搜索栏固定到标题时。
无论如何,我到目前为止已经完成了 => gif image 2
当我折叠 sliver 应用栏时,我的搜索栏正在缩小。我希望当我折叠 sliver 应用栏并修复上面标题中的搜索栏时,搜索不会缩小。这是我的代码

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
double changingHeight;
double appBarHeight;
bool appBarSearchShow = false;
final TextEditingController _filter = new TextEditingController();

List<String> itemList = [];

@override
void initState() {
for (int count = 0; count < 50; count++) {
itemList.add("Item $count");
}
changingHeight = 300;
}

@override
Widget build(BuildContext context) {
appBarHeight = MediaQuery.of(context).padding.top + kToolbarHeight;
return Scaffold(
backgroundColor: Colors.white,
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxScrolled) {
return <Widget>[createSilverAppBar()];
},
body: ListView.builder(
itemCount: itemList.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(itemList[index]),
),
);
})),
);
}

SliverAppBar createSilverAppBar() {
return SliverAppBar(
backgroundColor: Colors.white,
expandedHeight: 300,
floating: false,
pinned: true,
// title: appBarSearchShow == true
// ? CupertinoTextField(
// controller: _filter,
// keyboardType: TextInputType.text,
// placeholder: "Search..",
// placeholderStyle: TextStyle(
// color: Color(0xffC4C6CC),
// fontSize: 14.0,
// fontFamily: 'Brutal',
// ),
// prefix: Padding(
// padding: const EdgeInsets.fromLTRB(9.0, 6.0, 9.0, 6.0),
// child: Icon(
// Icons.search,
// ),
// ),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(8.0),
// color: Colors.white,
// ),
// )
// : Container(),
flexibleSpace: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
if (constraints.biggest.height == appBarHeight) {
appBarSearchShow = true;
} else {
appBarSearchShow = false;
}
return FlexibleSpaceBar(
collapseMode: CollapseMode.parallax,
titlePadding: EdgeInsets.only(bottom: 10),
centerTitle: true,
title: constraints.biggest.height != appBarHeight
? Container(
//margin: EdgeInsets.symmetric(horizontal: 10),
constraints: BoxConstraints(minHeight: 30, maxHeight: 30),
width: 220,
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,
),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Colors.white,
),
),
)
: Container(),
background: Container(
//height: constraints.maxHeight - 15,
color: Colors.white,
margin: EdgeInsets.only(bottom: 30),
child: Image.asset(
'assets/mainBackImage.jpg',
fit: BoxFit.cover,
),
),
);
}),
);
}
}
任何帮助,将不胜感激。

最佳答案

这是使搜索栏固定并阻止其缩小的解决方案:
您可以使用两个 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,
),
),
),
);
}
结果:
res
这是一个基于gif image 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

关于flutter - Flutter 中具有搜索功能的 sliver 应用栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63227401/

47 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com