You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:24:56