Android Flutter實(shí)現(xiàn)淘寶App的搜索推薦
前言
在很多 App 中,當(dāng)用戶輸入搜索內(nèi)容時(shí),往往會(huì)自動(dòng)匹配一些候選搜索內(nèi)容,以便讓用戶快速完成搜索內(nèi)容的輸入。同時(shí),也可以在候選的搜索內(nèi)容中根據(jù)用戶偏好“加塞”廣告,提高成交轉(zhuǎn)化率。比如在淘寶搜索“蘋果”這個(gè)詞時(shí),就會(huì)出現(xiàn)蘋果相關(guān)的候選選項(xiàng)。類似這樣的功能就需要用到輸入內(nèi)容的自動(dòng)填充。

這種功能可以自己去寫兩個(gè)獨(dú)立的組件,比如一個(gè)搜索框,一個(gè)候選內(nèi)容彈層,通過(guò)內(nèi)容聯(lián)動(dòng)來(lái)實(shí)現(xiàn)。不過(guò),F(xiàn)lutter 中其實(shí)有自帶的組件,叫做 AutoComplete。
AutoComplete 簡(jiǎn)介
AutoComplete是一個(gè)泛型類,組件定義如下。
class?Autocomplete<T?extends?Object>?extends?StatelessWidget?{
??const?Autocomplete({
????super.key,
????required?this.optionsBuilder,
????this.displayStringForOption?=?RawAutocomplete.defaultStringForOption,
????this.fieldViewBuilder?=?_defaultFieldViewBuilder,
????this.onSelected,
????this.optionsMaxHeight?=?200.0,
????this.optionsViewBuilder,
????this.initialValue,
??});
??//……其中泛型指的是候選內(nèi)容對(duì)象的類型,最簡(jiǎn)單的就是 String 類型,但是我們后臺(tái)返回的可能會(huì)是一個(gè)完整的對(duì)象,這個(gè)時(shí)候我們就可以定義為后臺(tái)對(duì)象對(duì)應(yīng)的實(shí)體類。具體的參數(shù)說(shuō)明如下:
optionsBuilder:選項(xiàng)內(nèi)容構(gòu)建函數(shù),實(shí)際上就是匹配用戶輸入的規(guī)則,我們可以基于用戶輸入的內(nèi)容去做二次處理,比如模糊匹配用戶輸入的內(nèi)容。displayStringForOption:后續(xù)內(nèi)容如何顯示,通常會(huì)顯示名稱、標(biāo)題之類的內(nèi)容,也可以根據(jù)需要自定義顯示內(nèi)容,例如地址就可以將省市區(qū)和詳細(xì)地址拼接起來(lái)。fieldViewBuilder:輸入框的構(gòu)建函數(shù),這個(gè)函數(shù)需要返回一個(gè)輸入框供用戶輸入,輸入框樣式可以自定義。onSelected:選中候選內(nèi)容項(xiàng)的回調(diào),通常我們會(huì)在這個(gè)方法里觸發(fā)搜索請(qǐng)求。optionsMaxHeight:候選項(xiàng)彈層的最大高度,超過(guò)這個(gè)高度后可以滾動(dòng)。optionsViewBuilder:候選項(xiàng)的彈層組件的構(gòu)建函數(shù),默認(rèn)是使用 Material 風(fēng)格的下拉列表視圖組件,也可以自定義候選彈層的組件。initialValue:初始值,比如根據(jù)用戶近期瀏覽記錄推薦一個(gè)候選的初始值。
實(shí)際應(yīng)用
下面我們以一個(gè)輸入國(guó)家檢索的應(yīng)用為例,我們準(zhǔn)備了一個(gè)Country類,其中有id和name字段。當(dāng)檢測(cè)到國(guó)家名稱匹配用戶輸入的文字時(shí),就會(huì)篩選出候選的國(guó)家,從而簡(jiǎn)化用戶的輸入過(guò)程。例如,用戶輸入“中”字,就會(huì)把“中國(guó)”這個(gè)候選項(xiàng)篩選出來(lái)。類似的場(chǎng)景也可以用于商品搜索推薦、支持輸入的下拉框等等。實(shí)現(xiàn)的效果如下圖所示。

示例代碼如下:
class?AutoCompleteDemo?extends?StatefulWidget?{
??const?AutoCompleteDemo({super.key});
??@override
??//?ignore:?library_private_types_in_public_api
??_AutoCompleteDemoState?createState()?=>?_AutoCompleteDemoState();
}
class?_AutoCompleteDemoState?extends?State<AutoCompleteDemo>?{
??final?List<Country>?countries?=?[
????Country(id:?1,?name:?'中國(guó)'),
????Country(id:?2,?name:?'美國(guó)'),
????Country(id:?3,?name:?'印度'),
????Country(id:?4,?name:?'俄羅斯'),
????Country(id:?5,?name:?'英國(guó)'),
????Country(id:?6,?name:?'巴西'),
????Country(id:?7,?name:?'法國(guó)'),
????Country(id:?8,?name:?'德國(guó)'),
??];
??var?selectedCountry?=?'';
??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????appBar:?AppBar(
????????title:?const?Text('AutoComplete?Demo'),
??????),
??????body:?Center(
????????child:?Autocomplete<Country>(
??????????optionsBuilder:?(TextEditingValue?textEditingValue)?{
????????????return?Future.delayed(const?Duration(milliseconds:?2000),?()?{
??????????????return?countries
??????????????????.where(
??????????????????????(country)?=>?country.name.contains(textEditingValue.text))
??????????????????.toList();
????????????});
??????????},
??????????onSelected:?(Country?country)?{
????????????selectedCountry?=?country.name;
??????????},
??????????fieldViewBuilder:?(BuildContext?context,
??????????????TextEditingController?textEditingController,
??????????????FocusNode?focusNode,
??????????????VoidCallback?onFieldSubmitted)?{
????????????return?TextField(
??????????????controller:?textEditingController,
??????????????focusNode:?focusNode,
??????????????onChanged:?(text)?{
????????????????selectedCountry?=?text;
??????????????},
??????????????decoration:?const?InputDecoration(
????????????????labelText:?'國(guó)家',
??????????????),
????????????);
??????????},
??????????displayStringForOption:?(Country?country)?=>
??????????????'[${country.id}]?${country.name}',
??????????initialValue:?TextEditingValue(text:?selectedCountry),
????????),
??????),
????);
??}
}
class?Country?{
??final?int?id;
??final?String?name;
??Country({required?this.id,?required?this.name});
}這里我們使用了Country這個(gè)類作為AutoComplete的泛型參數(shù),這樣就可以支持對(duì)Country列表數(shù)據(jù)進(jìn)行處理了。具體的邏輯說(shuō)明如下:
optionsBuilder:我們采用了一個(gè)Future延時(shí)來(lái)模擬后臺(tái)數(shù)據(jù)請(qǐng)求,當(dāng)然,如果選項(xiàng)數(shù)據(jù)是固定的,可以進(jìn)入頁(yè)面的時(shí)候一次請(qǐng)求好就行。如果是要后臺(tái)配合搜索的,那么每次輸入都可以請(qǐng)求匹配的候選數(shù)據(jù)。這里實(shí)際處理就是篩選出國(guó)家名稱中包含用戶輸入內(nèi)容的列表。onSelected:選中后的操作,這里只是更新選項(xiàng)值,實(shí)際如果是搜索商品就可以直接攜帶搜索關(guān)鍵詞跳轉(zhuǎn)到搜索結(jié)果頁(yè)面。fieldViewBuilder:這里用于構(gòu)建一個(gè)輸入框,輸入框的樣式可以根據(jù)自己需要定義。如果要單獨(dú)控制輸入框,比如輸入內(nèi)容,獲取焦點(diǎn)等,可以定義一個(gè)TextEditingController對(duì)象和FocusNode對(duì)象來(lái)存儲(chǔ)回調(diào)函數(shù)的textEditingController和focusNode。這兩個(gè)參數(shù)是在AutoComplete類里面定義的。displayStringForOption:候選項(xiàng)的顯示(包括選中后的文本框),這種可以用于將一個(gè)對(duì)象的幾個(gè)字符串拼接起來(lái),例如前面講到的地址,這里我們演示是將id和name拼接起來(lái)了。initialValue:輸入框的初始值,如果是商品搜索,可以根據(jù)用戶近期的瀏覽記錄(或廣告追蹤記錄)展示推薦的搜索內(nèi)容,這個(gè)在電商App經(jīng)??吹健?/li>
以上就是Android Flutter實(shí)現(xiàn)淘寶App的搜索推薦的詳細(xì)內(nèi)容,更多關(guān)于Flutter淘寶搜索推薦的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android視頻懸浮窗口實(shí)現(xiàn)的示例代碼
這篇文章主要介紹了Android視頻懸浮窗口實(shí)現(xiàn)的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
Android開發(fā)高仿課程表的布局實(shí)例詳解
這篇文章主要介紹了Android開發(fā)高仿課程表的布局實(shí)例詳解的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-10-10
android之BroadcastReceiver應(yīng)用詳解
這篇文章主要介紹了android之BroadcastReceiver應(yīng)用詳解,BroadcastReceiver也就是“廣播接收者”的意思,顧名思義,它就是用來(lái)接收來(lái)自系統(tǒng)和應(yīng)用中的廣播。有興趣的可以了解一下。2016-12-12
Android 使用FragmentTabHost實(shí)現(xiàn)底部菜單功能
這篇文章主要介紹了Android 使用FragmentTabHost實(shí)現(xiàn)底部菜單功能,詳細(xì)給大家介紹了FragmentTabHost配合Fragment的使用方法,需要的朋友可以參考下2017-12-12
android 加載本地聯(lián)系人實(shí)現(xiàn)方法
在android開發(fā)過(guò)程中,有些功能需要訪問本地聯(lián)系人列表,本人搜集整理了一番,拿出來(lái)和大家分享一下,希望可以幫助你們2012-12-12
Android下的POS打印機(jī)調(diào)用的簡(jiǎn)單實(shí)現(xiàn)
本篇文章主要介紹了Android下的POS打印機(jī)調(diào)用的簡(jiǎn)單實(shí)現(xiàn),非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-04-04
Flutter滾動(dòng)組件之SingleChildScrollView使用詳解
這篇文章主要為大家詳細(xì)介紹了Flutter滾動(dòng)組件之SingleChildScrollView使用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
Android M(6.x)使用OkHttp包解析和發(fā)送JSON請(qǐng)求的教程
Android 6.0采用的SPDY支持HTTP上GZIP壓縮的傳輸,這使得OkHttp包的功能能夠進(jìn)一步被利用,本文我們來(lái)總結(jié)一下Android M(6.0)使用OkHttp包解析和發(fā)送JSON請(qǐng)求的教程2016-07-07
詳解flutter如何實(shí)現(xiàn)局部導(dǎo)航管理
這篇文章主要為大家介紹了詳解flutter如何實(shí)現(xiàn)局部導(dǎo)航管理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01

