MaterialSearchBar搜索历史持久化实现问题求助
解决MaterialSearchBar搜索历史持久化问题
问题分析
你的代码存在几个关键问题导致搜索历史无法持久化:
saveSearchSuggestionToDisk中错误地向List<String>添加SaveSearchModel对象,导致Gson序列化失败loadSearchSuggestionFromDisk最终返回的是searchBar.getLastSuggestions()而非从SharedPreferences加载的数据,且自定义List实现完全无效onSearchConfirmed未将搜索词添加到搜索历史列表中,导致searchBar.getLastSuggestions()始终没有更新- 不需要额外创建
SaveSearchModel,MaterialSearchBar的历史就是String类型的列表
正确实现代码
以下是修复后的完整代码:
public class MainActivity extends AppCompatActivity implements MaterialSearchBar.OnSearchActionListener { private MaterialSearchBar searchBar; private static final String PREF_NAME = "SEARCH_HISTORY"; private static final String KEY_SEARCH_DATA = "search_data"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); searchBar = findViewById(R.id.search); searchBar.setHint("Your product"); searchBar.setSpeechMode(true); searchBar.setOnSearchActionListener(this); // 加载本地保存的搜索历史 List<String> lastSearches = loadSearchSuggestionFromDisk(); searchBar.setLastSuggestions(lastSearches); } // 保存搜索历史到本地 private void saveSearchSuggestionToDisk(List<String> lastSuggestions) { SharedPreferences sharedPreferences = getSharedPreferences(PREF_NAME, MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); Gson gson = new Gson(); String json = gson.toJson(lastSuggestions); editor.putString(KEY_SEARCH_DATA, json); editor.apply(); } // 从本地加载搜索历史 private List<String> loadSearchSuggestionFromDisk() { SharedPreferences sharedPreferences = getSharedPreferences(PREF_NAME, MODE_PRIVATE); Gson gson = new Gson(); String json = sharedPreferences.getString(KEY_SEARCH_DATA, null); Type type = new TypeToken<List<String>>() {}.getType(); List<String> searchHistory = gson.fromJson(json, type); // 如果没有历史数据,返回空的ArrayList return searchHistory == null ? new ArrayList<>() : searchHistory; } @Override public void onSearchStateChanged(boolean enabled) { String state = enabled ? "enable" : "disable"; Toast.makeText(this, "Search " + state, Toast.LENGTH_SHORT).show(); } @Override public void onSearchConfirmed(CharSequence charSequence) { String searchText = charSequence.toString(); Toast.makeText(this, "Searching " + searchText + " ...", Toast.LENGTH_SHORT).show(); // 将搜索词添加到搜索历史,避免重复 List<String> currentHistory = searchBar.getLastSuggestions(); if (!currentHistory.contains(searchText)) { currentHistory.add(searchText); // 更新SearchBar的历史列表 searchBar.setLastSuggestions(currentHistory); } } @Override public void onButtonClicked(int buttonCode) { switch (buttonCode) { case MaterialSearchBar.BUTTON_NAVIGATION: Toast.makeText(MainActivity.this, "Button Nav ", Toast.LENGTH_SHORT).show(); break; case MaterialSearchBar.BUTTON_SPEECH: Toast.makeText(this, "Search", Toast.LENGTH_SHORT).show(); break; } } @Override protected void onDestroy() { super.onDestroy(); // 保存当前搜索历史 saveSearchSuggestionToDisk(searchBar.getLastSuggestions()); } }
关键修复点
- 移除不必要的
SaveSearchModel:直接使用List<String>存储搜索历史,符合MaterialSearchBar的要求 - 修复保存逻辑:正确序列化
List<String>为JSON字符串,避免类型错误 - 修复加载逻辑:加载后返回正确的历史列表,空数据时返回空
ArrayList而非无效的自定义List - 添加搜索词到历史:在
onSearchConfirmed中将搜索词加入历史,确保searchBar.getLastSuggestions()有数据可保存 - 避免重复历史:添加前检查是否已存在,防止重复条目
内容的提问来源于stack exchange,提问作者Eypro Corp
相关产品推荐
相关产品推荐

