Android 设置搜索功能

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

Android Settings 从 Q 平台开始将搜索界面单独放到了 SettingsIntelligence 中代码路径packages/apps/SettingsIntelligence 。

查看 SettingsIntelligence 应用 AndroidManifest发现启动 activity 为 SearchActivity查看该 Activity。可以看到onCreate() 方法中加载了一个 Fragment 用来填充 main_contentFragment 有两个选择其中 CarSearchFragment 是适配车机系统的此处不做详解主要跟进下 SearchFragment。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ……
    final LoaderManager loaderManager = getLoaderManager();
    mSearchAdapter = new SearchResultsAdapter(this /* fragment */);
    mSavedQueryController = new SavedQueryController(
        getContext(), loaderManager, mSearchAdapter);
    mSearchFeatureProvider.initFeedbackButton();
    ……
    mSearchFeatureProvider.updateIndexAsync(getContext(), this /* indexingCallback */);
    ……
}

在 PreIndexDataCollector.java 中的最后 get*** 函数中创建 ContentResolver 来查询获取数据。

而数据的来源就是 Settings 中 SettingsSearchIndexablesProvider , SettingsSearchIndexablesProvider 继承自 android.provider.SearchIndexablesProvider.java

<provider
    android:name=".search.SettingsSearchIndexablesProvider"
    android:authorities="com.android.settings"
    android:multiprocess="false"
    android:grantUriPermissions="true"
    android:permission="android.permission.READ_SEARCH_INDEXABLES"
    android:exported="true">
    <intent-filter>
        <action android:name="android.content.action.SEARCH_INDEXABLES_PROVIDER" />
    </intent-filter>
</provider>

SearchIndexablesProvider 中只有一个 query 是有作用的其他几个 insert delete update 操作都是抛出异常。 query 中对上面 PreIndexDataCollector 中的请求进行具体处理如下。

queryXmlResources 等几个操作具体实现就回到 Settings 应用模块中了在 SettingsSearchIndexablesProvider 中进行实现以 queryXmlResources 为例

最终通过 getProviderValues() 获取所有的带 @SearchIndexable 注释的类。再获取里面的 Indexable.SearchIndexProvider 内部类所有的相关类里面的这个内部类都是一样的命名好找

Settings 中常用方法期间 Settings 中的 BaseSearchIndexProvider 需要着重关注下该类实现 Indexable.SearchIndexProvider 接口直接给 Settings 的 SettingsSearchIndexablesProvider 提供数据。以后工作中会经常用到 BaseSearchIndexProvider 实现的几个方法用来隐藏搜索项添加搜索项。以下方法需要在各自的 fragment 中重写来实现。

// 添加 XML 中数据到搜索项
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
                        Context context, boolean enabled) {
    final SearchIndexableResource sir = new SearchIndexableResource(context);
    sir.xmlResId = R.xml.connected_devices_advanced;
    return Arrays.asList(sir);
}

// 添加 Controller 中数据到搜索项
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
                        Context context) {
    return buildPreferenceControllers(
    context, null /* parent */, null /* authorities*/);
}

// 添加不可搜索项
@Override
public List<String> getNonIndexableKeys(Context context) {
    final List<String> keys = super.getNonIndexableKeys(context);
    return keys;
}

// 整个界面不可搜索
@Override
protected boolean isPageSearchEnabled(Context context) {
    return false;
}

这里面重要的几个方法功能大致介绍下。首先构造函数中的 R.xml.display_settings 这可以看下 BaseSearchIndexProvider 类中其实就是给定 getXmlResourcesToIndex 方法的xml参数。添加xml中所有 key 的搜索项目。

getNonIndexableKeys 这个方法中返回就是无需搜索的从搜索列表中移除的 key 的集合。

isPageSearchEnabled 这个返回 false 则表示这个 display_settings xml 中所有的 key 都不需要的搜索全部移除。具体使用是在 BaseSearchIndexProvider 中。

通过在xml文件中配置也可达到不可搜索的目的
settings:searchable=“false”
settings:keywords=“keywords1, keywords2, keywords3”

searchable控制此项是否可搜索
keywords为此项的关键词也可以被触发关键词而搜索到

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: android