在应用栏中创建一个在 Flutter 中向下滚动时变成图标的搜索?
Creating a Search in appbar that turns into an icon when scrolling down in Flutter?
我已经创建了搜索栏,我需要给它添加一个功能,这样每当用户向下滚动时,搜索栏就会变成应用栏中的一个图标,可以再次点击它展开。
这是应用栏容器
Container(
height: 122,
color: AppColors.kDefaultPink,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
//Location text
SizedBox(height: 10.0,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.location_on,
color: Colors.white,
),
SizedBox(width: 12.0),
Text("Delhi NCR",style: TextStyle(color: Colors.white, fontSize: 18.0),),
],
),
SizedBox(height: 20.0,),
//SearchBOX
SearchBox(onChanged: (value) {}),
],
),
),
),
这是将出现在应用栏中的搜索栏代码
import 'package:flutter/material.dart';
import 'package:zattireuserapp/views/AppColors.dart';
class SearchBox extends StatelessWidget {
final ValueChanged onChanged;
const SearchBox({Key key, this.onChanged}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: Container(
width: 390,
height: 45,
margin: EdgeInsets.symmetric(horizontal: 22.0),
decoration: BoxDecoration(
color: Colors.white.withOpacity(1),
borderRadius: BorderRadius.circular(12),
),
child: TextField(
onChanged: onChanged,
style: TextStyle(color: AppColors.blackColor),
decoration: InputDecoration(
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
prefixIcon: Icon(Icons.search),
hintText: 'Search for anything',
hintStyle: TextStyle(fontSize: 15),
),
),
),
);
}
}
您可以使用 LayoutBuilder 获得 sliver AppBar 的最大高度。当biggest.height = 80.0时,实际上意味着sliver appbar被折叠了。
这是一个例子:
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
home: MyApp(),
));
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
var top = 0.0;
ScrollController _scrollController;
@override
void initState() {
_scrollController = ScrollController(keepScrollOffset: true);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
controller: _scrollController,
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: 200.0,
floating: false,
pinned: true,
flexibleSpace: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
top = constraints.biggest.height;
return FlexibleSpaceBar(
centerTitle: true,
title: top >= 80 ? TextField() : IconButton(icon: Icon(Icons.search), onPressed: () => _scrollController.jumpTo(0)) // condition
);
})),
];
},body: ListView.builder(
itemCount: 100,
itemBuilder: (context,index){
return Text("List Item: " + index.toString());
},
),
));
}
}
对于混乱的代码,我深表歉意,但我希望你能理解
我已经创建了搜索栏,我需要给它添加一个功能,这样每当用户向下滚动时,搜索栏就会变成应用栏中的一个图标,可以再次点击它展开。
这是应用栏容器
Container(
height: 122,
color: AppColors.kDefaultPink,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
//Location text
SizedBox(height: 10.0,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.location_on,
color: Colors.white,
),
SizedBox(width: 12.0),
Text("Delhi NCR",style: TextStyle(color: Colors.white, fontSize: 18.0),),
],
),
SizedBox(height: 20.0,),
//SearchBOX
SearchBox(onChanged: (value) {}),
],
),
),
),
这是将出现在应用栏中的搜索栏代码
import 'package:flutter/material.dart';
import 'package:zattireuserapp/views/AppColors.dart';
class SearchBox extends StatelessWidget {
final ValueChanged onChanged;
const SearchBox({Key key, this.onChanged}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: Container(
width: 390,
height: 45,
margin: EdgeInsets.symmetric(horizontal: 22.0),
decoration: BoxDecoration(
color: Colors.white.withOpacity(1),
borderRadius: BorderRadius.circular(12),
),
child: TextField(
onChanged: onChanged,
style: TextStyle(color: AppColors.blackColor),
decoration: InputDecoration(
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
prefixIcon: Icon(Icons.search),
hintText: 'Search for anything',
hintStyle: TextStyle(fontSize: 15),
),
),
),
);
}
}
您可以使用 LayoutBuilder 获得 sliver AppBar 的最大高度。当biggest.height = 80.0时,实际上意味着sliver appbar被折叠了。
这是一个例子:
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
home: MyApp(),
));
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
var top = 0.0;
ScrollController _scrollController;
@override
void initState() {
_scrollController = ScrollController(keepScrollOffset: true);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
controller: _scrollController,
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: 200.0,
floating: false,
pinned: true,
flexibleSpace: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
top = constraints.biggest.height;
return FlexibleSpaceBar(
centerTitle: true,
title: top >= 80 ? TextField() : IconButton(icon: Icon(Icons.search), onPressed: () => _scrollController.jumpTo(0)) // condition
);
})),
];
},body: ListView.builder(
itemCount: 100,
itemBuilder: (context,index){
return Text("List Item: " + index.toString());
},
),
));
}
}
对于混乱的代码,我深表歉意,但我希望你能理解