Flutter实现漂亮的搜索框

最终效果图:


import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
///圆角搜索框
class YmSearchBar extends StatefulWidget {
///搜索框上显示的文案
String hint;
///搜索框的圆角
double defaultBorderRadius;
EdgeInsets margin;
EdgeInsets padding;
///如果考虑不需要水波纹效果那么就可以设置颜色为透明色
Color splashColor;
///文本输入框焦点控制
FocusNode? focusNode;
///文本输入框控制器
TextEditingController? controller;
///点击键盘上的回车键的回调
Function(String text)? onSubmitted;
///清楚搜索回调
Function? clearCallback;
///返回键的回调
Function()? onBackCallback;
///输入文本的长度限制
int inputKeyWordsLength;
///输入框文字大小
double fontSize;
///是否显示左侧的返回键
bool isShowBackButton;
///搜索框的长度
double width;
///搜索框的高度
double height;
YmSearchBar(
{
this.hint = "搜索",
this.defaultBorderRadius = 30.0,
this.margin = const EdgeInsets.only(top: 10.0, bottom: 10.0),
this.padding = const EdgeInsets.only(left: 12),
this.splashColor = const Color(0xFFD6D6D6),
this.focusNode,
this.controller,
this.onSubmitted,
this.onBackCallback,
this.clearCallback,
this.inputKeyWordsLength = 20,
this.fontSize = 14,
this.isShowBackButton = false,
this.width = 200,
this.height = 60
}
) {
this.height = this.defaultBorderRadius * 2;
}
@override
State createState() {
return SearchTextFieldBarState();
}
}
class SearchTextFieldBarState extends State {
///为true 时显示清除选项
bool showClear = false;
///文本输入框的默认使用控制器
TextEditingController defaultTextController = TextEditingController();
@override
void initState() {
super.initState();
///创建默认的焦点控制
if (widget.focusNode == null) {
widget.focusNode = new FocusNode();
}
}
@override
Widget build(BuildContext context) {
return Container(
///外边距
margin: widget.margin,
///水平方向线性排列
child: Row(
children: [
///左侧的返回按钮
buildLeftBackWidget(),
///右侧的搜索框内容区域
buildContentContainer(),
],
),
);
}
///构建左侧的返回按钮
Widget buildLeftBackWidget() {
///当用在APPBar的位置时
///常常需要配合一个返回按钮
if (widget.isShowBackButton) {
///返回键按钮
return BackButton(
color: Colors.white,
onPressed: () {
///返回事件回调
if (widget.onBackCallback != null) {
widget.onBackCallback!();
} else {
///直接关闭当前页面
Navigator.of(context).pop();
}
},
);
} else {
///当不需要显示返回按钮时
///设置一个空视图
return Container();
}
}
///构建搜索框的显示区域[Container]
LayoutBuilder buildContainer(BuildContext context) {
return LayoutBuilder(builder: (context, BoxConstraints constraints) {
return buildContentContainer();
});
}
///构建搜索框的显示区域[Container]
Container buildContentContainer() {
return Container(
height: widget.height,
///获取当前StatelessWidget的宽度
width: widget.width,
///对齐方式
alignment: Alignment(-1, 0),
///内边距
padding: widget.padding,
///圆角边框
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(widget.defaultBorderRadius),
),
child: buildRow(),
);
}
///构建搜索图标与显示文本
Row buildRow() {
return Row(
///左对齐
mainAxisAlignment: MainAxisAlignment.start,
///居左
crossAxisAlignment: CrossAxisAlignment.center,
children:[
///左侧的搜索图标
Icon(
Icons.search,
color: Colors.pink,
size: 24.0,
semanticLabel: 'Text to announce in accessibility modes',
),
SizedBox(
width: 8.0,
),
///中间的输入框
Expanded(
flex: 1,
child: Container(
alignment: Alignment(-1, 0),
child: buildTextField(),
),
),
///右侧的清除小按钮
buildClearButton(),
],
);
}
///lib/demo/search_textfield_bar.dart
///构建搜索输入TextField
TextField buildTextField() {
return TextField(
///设置键盘的类型
keyboardType: TextInputType.text,
///键盘回车键的样式为搜索
textInputAction: TextInputAction.search,
///只有苹果手机上有效果
keyboardAppearance: Brightness.dark,
///控制器配置
controller:
widget.controller == null ? defaultTextController : widget.controller,
///最大行数
maxLines: 1,
///输入文本格式过滤
inputFormatters: [
///输入的内容长度限制
LengthLimitingTextInputFormatter(widget.inputKeyWordsLength),
],
///当输入文本时实时回调
onChanged: (text) {
///多层判断 优化刷新
///只有当有改变时再刷新
if (text.length > 0) {
if (!showClear) {
showClear = true;
setState(() {});
}
} else {
if (showClear) {
showClear = false;
setState(() {});
}
}
},
///点击键盘上的回车键
///或者是搜索按钮的回调
onSubmitted: (text) {
if (widget.onSubmitted != null) {
widget.onSubmitted!(text);
}
},
///输入框不自动获取焦点
autofocus: false,
focusNode: widget.focusNode,
style: TextStyle(
fontSize: widget.fontSize,
color: Colors.black54,
fontWeight: FontWeight.w300),
///输入框的边框装饰
decoration: InputDecoration(
//重要 用于编辑框对齐
isDense: true,
///清除文本内边跑
contentPadding: EdgeInsets.zero,
///不设置边框
border: InputBorder.none,
///设置提示文本
hintText: widget.hint,
///设置提示文本的样式
hintStyle: TextStyle(
fontSize: widget.fontSize,
color: Color(0xff999999),
)),
);
}
///清除按键
///当文本框有内容输入时显示清除按钮
buildClearButton() {
///当文本输入框中有内容时才显示清除按钮
if (showClear) {
return IconButton(
icon: Icon(
Icons.clear,
size: 24.0,
color: Color(0xffacacac),
),
onPressed: () {
if(widget.controller==null){
defaultTextController.clear();
}else{
widget.controller!.text = "";
}
if (widget.clearCallback != null) {
widget.clearCallback!();
}
},
);
} else {
return Container();
}
}
}

把这个文件放到任意位置,使用:

child: YmSearchBar(
hint: "关键词",
width: MediaQuery.of(context).size.width - 40,
onSubmitted: (text){
print("搜索$text");
_searchTextValue = text;
_loadData();
},
clearCallback:(){
_searchTextValue = "";
_loadData();
},
onBackCallback: () {
}
),


本站内容来源于作者发布和网络转载,如有版权相关问题请及时与我们取得联系,我们将立即删除。

 关于作者
 热门教程
通过Git下载和提交代码的命令记录
安装好git后: 1、配置邮箱 git config --global user.name ymbok git con
2023-08-15
剑道仙尊
64
通过ADB在Android系统中快捷截屏和录屏的方法
连上ADB线后: 截图 创建一个BAT文件,用于截图,直接双击运行即可将图片保存到D:\screenshot目录,提前
2023-08-15
剑道仙尊
122
Android12 源码下载与编译
下载Android12 源码 sudo apt-get update 安装curl sudo apt install
2023-04-25
剑道仙尊
128
android生成签名文件jks并获取SHA1
打开Android Studio终端,输入: keytool -genkey -alias app -keyalg R
2022-07-13
剑道仙尊
96
Flutter开发APP更改状态栏文字颜色
void main(){ runApp(MyApp()); /// 状态栏文字黑色 SystemChrome
2022-06-09
剑道仙尊
136
Android Swicth按钮样式自定义
<Switch android:id="@+id/switch_btn" android:layout_wi
2022-06-07
剑道仙尊
142
Pagging3写起来太麻烦,简单封装及其简单
Pagging3分页写起来很麻烦,这里分享一下我的简化开发的方法,思路就是把获取数据的函数分离出来 首先定义一个基础的
2022-06-07
剑道仙尊
213
在项目中使用Hilt Retrofit使用总结
直接开始,首先我们看看怎么使用Hilt编写 Retrofit 接口请求类 用@Provides注解定义可注入的实例的提
2022-06-07
剑道仙尊
206
Android Jetpack Paging 3 下拉刷新和加载更多代码示例
使用Paging3实现列表的下拉刷新和加载更多 首先定义列表布局文件 <androidx.swiperefres
2022-06-07
剑道仙尊
442
StatefulBuilder实现Dialog的刷新
在Flutter中使用Dialog时,因为 showDialog返回的context与当前页面的 context不是同
2022-06-07
剑道仙尊
139