search_bar.dart
enum SearchBarType { home, normal, homeLight }
/// 通用搜索组件
class SearchBar extends StatefulWidget {
final bool enabled;
// 是否隐藏左侧图标
final bool hideLeft;
// 搜索框类型
final SearchBarType searchBarType;
// 提示信息
final String hint;
// 默认输入内容
final String defaultText;
// 左侧图标点击
final void Function() leftButtonClick;
// 右侧图标点击
final void Function() rightButtonClick;
// 语音图标点击
final void Function() speackClick;
// 输入框点击
final void Function() inputBoxClick;
// 输入框文本变化
final ValueChanged onChanged;
const SearchBar(
{Key key,
this.enabled = true,
this.hideLeft,
this.searchBarType = SearchBarType.normal,
this.hint,
this.defaultText,
this.leftButtonClick,
this.rightButtonClick,
this.speackClick,
this.inputBoxClick,
this.onChanged})
: super(key: key);
@override
_SearchBarState createState() => _SearchBarState();
}
class _SearchBarState extends State {
// 是否显示清除按钮
bool showClear = false;
// 输入框文本控制器
final TextEditingController _controller = TextEditingController();
@override
void initState() {
super.initState();
// 初始化输入框文本内容
if (widget.defaultText != null) {
setState(() {
_controller.text = widget.defaultText;
});
}
}
@override
Widget build(BuildContext context) {
// 根据输入框类型构建不同样式的输入框
return widget.searchBarType == SearchBarType.normal
? _genNormalSearch()
: _genHomeSearch();
}
/// 构建首页搜索组件样式
_genHomeSearch() {
return Container(
child: Row(
children: [
// 左侧图标
_wrapTap(
Container(
padding: EdgeInsets.fromLTRB(6, 5, 5, 5),
child: Row(
children: [
Text('上海',
style: TextStyle(
color: _homeFrontColor(), fontSize: 14)),
Icon(Icons.expand_more,
color: _homeFrontColor(), size: 22)
],
)),
widget.leftButtonClick),
// 搜索框
Expanded(child: _inputBox(), flex: 1),
// 右侧消息图标
_wrapTap(
Container(
padding: EdgeInsets.fromLTRB(10, 5, 10, 5),
child: Icon(
Icons.comment,
color: _homeFrontColor(),
size: 26,
),
),
widget.rightButtonClick)
],
),
);
}
/// 构建通用搜索组件样式
_genNormalSearch() {
return Container(
child: Row(
children: [
// 左侧图标
_wrapTap(
Container(
padding: EdgeInsets.fromLTRB(6, 5, 10, 5),
child: widget.hideLeft ?? false
? null
: Icon(
Icons.arrow_back_ios,
size: 26,
color: Colors.grey,
),
),
widget.leftButtonClick),
// 搜索框
Expanded(child: _inputBox(), flex: 1),
// 右侧搜索文字
_wrapTap(
Container(
padding: EdgeInsets.fromLTRB(10, 5, 10, 5),
child: Text('搜索',
style: TextStyle(color: Colors.blue, fontSize: 17)),
),
widget.rightButtonClick)
],
),
);
}
/// 构建搜索框
Widget _inputBox() {
Color inputBoxColor;
if (widget.searchBarType == SearchBarType.normal) {
inputBoxColor = Colors.white;
} else {
inputBoxColor = Color(int.parse('0xffEDEDED'));
}
return Container(
height: 30,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
// 搜索组件样式(设置背景色以及圆角)
decoration: BoxDecoration(
color: inputBoxColor,
borderRadius: BorderRadius.circular(
widget.searchBarType == SearchBarType.normal ? 5 : 15)),
child: Row(
children: [
//搜索图标
Icon(Icons.search,
size: 20,
color: widget.searchBarType == SearchBarType.normal
? Color(0xffA9A9A9)
: Colors.blue),
// 输入框
Expanded(
child: widget.searchBarType == SearchBarType.normal
? TextField(
controller: _controller,
onChanged: _onChanged,
autofocus: true,
style: TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.w300),
// 输入文本样式
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(5, 0, 5, 0),
border: InputBorder.none,
hintText: widget.hint ?? '',
hintStyle: TextStyle(fontSize: 15)),
)
: _wrapTap(
// 首页搜索组件样式
Container(
child: Text(
widget.defaultText,
style: TextStyle(fontSize: 13, color: Colors.grey),
),
),
widget.inputBoxClick)),
!showClear
? _wrapTap(
// 语音图标
Icon(
Icons.mic,
size: 22,
color: widget.searchBarType == SearchBarType.normal
? Colors.blue
: Colors.grey,
),
widget.speackClick)
: _wrapTap(
// 清除图标
Icon(
Icons.clear,
size: 22,
color: Colors.grey,
), () {
// 清空搜索内容
setState(() {
_controller.clear();
});
// 清空输入框内容
_onChanged('');
})
],
),
);
}
/// 输入框监听文本变化
_onChanged(String text) {
if (text.length > 0) {
setState(() {
showClear = true;
});
} else {
setState(() {
showClear = false;
});
}
// 回调输入的内容
if (widget.onChanged != null) {
widget.onChanged(text);
}
}
/// 首页前景色
_homeFrontColor() {
return widget.searchBarType == SearchBarType.normal
? Colors.black54
: Colors.white;
}
// 返回自带点击事件的widget
_wrapTap(Widget widget, void Function() callback) {
return GestureDetector(
onTap: () {
if (callback != null) callback();
},
child: widget,
);
}
}
使用
SearchBar(
searchBarType: appBarAlpha > 0.2
? SearchBarType.homeLight
: SearchBarType.home,
inputBoxClick: _jumpToSearch,
speackClick: _jumpToSpeak,
// 输入框提示信息
defaultText: SEARCH_BAR_DEFAULT_TEXT,
leftButtonClick: () {},
)
/// 跳转到搜索页
void _jumpToSearch() {}
/// 跳转到语音识别页面
void _jumpToSpeak() {}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)