先建立一個主文件,繼承StatelessWidget
,然后在home屬性中加入SearchBarDemo
,這是一個自定義的Widget,主要代碼都在這個文件中。
import 'package:flutter/material.dart'; import 'search_bar_demo.dart'; void main() =>runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title:'Flutter Demo', theme: ThemeData.light(), home: SearchBarDemo() ); } }
然后是搜索頁面,里面包含數據及搜索功能。
工作中這些數據是后台傳遞給我們,或者寫成配置文件的,這里我們就以List的方式代替了。我們在這個文件中定義了兩個List:
const searchList = [ 'jiejie-大長腿', 'jiejie-水蛇腰', 'gege-帥氣歐巴', 'gege-小鮮肉' ]; const recentSuggest = [ '推薦-1', '推薦-2', ];
點擊搜索按鈕
class SearchBarDemo extends StatefulWidget { _SearchBarDemoState createState() => _SearchBarDemoState(); } class _SearchBarDemoState extends State<SearchBarDemo> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('SearchBarDemo'), actions: <Widget>[ IconButton( icon: Icon(Icons.search), onPressed: (){ showSearch(context: context,delegate: SearchBarDelegate()); }, ) ], ), ); } }
在點擊圖標時執行SearchBarDelegate
類,這個類繼承與SearchDelegate
類,繼承后要重寫里邊的四個方法。
重寫buildActions方法:
buildActions
方法時搜索條右側的按鈕執行方法,我們在這里方法里放入一個clear圖標。 當點擊圖片時,清空搜索的內容。
buildLeading 方法重寫
這個時搜索欄左側的圖標和功能的編寫,這里我們才用AnimatedIcon
,然后在點擊時關閉整個搜索頁面。
buildResults方法重寫
buildResults
方法,是搜到到內容后的展現,因為我們的數據都是模擬的,所以我這里就使用最簡單的Container
+Card
組件進行演示了。
buildSuggestions方法重寫
這個方法主要的作用就是設置推薦,就是我們輸入一個字,然后自動為我們推送相關的搜索結果。
class SearchBarDelegate extends SearchDelegate<String>{ //清空按鈕 @override List<Widget>buildActions(BuildContext context){ return [ IconButton( icon: Icon(Icons.clear), onPressed: () => query = "", //搜索值為空 ) ]; } //返回上級按鈕 @override Widget buildLeading(BuildContext context) { return IconButton( icon: AnimatedIcon( icon: AnimatedIcons.menu_arrow, progress: transitionAnimation ), onPressed: () => close(context, null) //點擊時關閉整個搜索頁面 ); } //搜到到內容后的展現 @override Widget buildResults(BuildContext context){ return Container( width: 100.0, height:100.0, child: Card( color:Colors.redAccent, child: Center( child: Text(query), ), ), ); } //設置推薦 @override Widget buildSuggestions(BuildContext context){ final suggestionsList= query.isEmpty ? recentSuggest : searchList.where((input)=> input.startsWith(query)).toList(); return ListView.builder( itemCount:suggestionsList.length, itemBuilder: (context,index) => ListTile( title: RichText( //富文本 text: TextSpan( text: suggestionsList[index].substring(0,query.length), style: TextStyle(color: Colors.black,fontWeight: FontWeight.bold), children: [ TextSpan( text: suggestionsList[index].substring(query.length), style: TextStyle(color: Colors.grey) ) ] ), ), ), ); } }
完整的search_bar_demo.dart文件代碼如下:
import 'package:flutter/material.dart'; const searchList = [ 'jiejie-大長腿', 'jiejie-水蛇腰', 'gege-帥氣歐巴', 'gege-小鮮肉' ]; const recentSuggest = [ '推薦-1', '推薦-2', ]; class SearchBarDemo extends StatefulWidget { _SearchBarDemoState createState() => _SearchBarDemoState(); } class _SearchBarDemoState extends State<SearchBarDemo> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('SearchBarDemo'), actions: <Widget>[ IconButton( icon: Icon(Icons.search), onPressed: (){ showSearch(context: context,delegate: SearchBarDelegate()); }, ) ], ), ); } } class SearchBarDelegate extends SearchDelegate<String>{ //清空按鈕 @override List<Widget>buildActions(BuildContext context){ return [ IconButton( icon: Icon(Icons.clear), onPressed: () => query = "", //搜索值為空 ) ]; } //返回上級按鈕 @override Widget buildLeading(BuildContext context) { return IconButton( icon: AnimatedIcon( icon: AnimatedIcons.menu_arrow, progress: transitionAnimation ), onPressed: () => close(context, null) //點擊時關閉整個搜索頁面 ); } //搜到到內容后的展現 @override Widget buildResults(BuildContext context){ return Container( width: 100.0, height:100.0, child: Card( color:Colors.redAccent, child: Center( child: Text(query), ), ), ); } //設置推薦 @override Widget buildSuggestions(BuildContext context){ final suggestionsList= query.isEmpty ? recentSuggest : searchList.where((input)=> input.startsWith(query)).toList(); return ListView.builder( itemCount:suggestionsList.length, itemBuilder: (context,index) => ListTile( title: RichText( //富文本 text: TextSpan( text: suggestionsList[index].substring(0,query.length), style: TextStyle(color: Colors.black,fontWeight: FontWeight.bold), children: [ TextSpan( text: suggestionsList[index].substring(query.length), style: TextStyle(color: Colors.grey) ) ] ), ), ), ); } }