Android 5.0 L版本搜索框實現淺析


      在
Android 5.0中增加了設置選項搜索功能。當你進入到設置菜單後,可以點擊右上角的放大鏡圖標,它會在每個設置界面中出現,你可以在裏面尋找想要設置的內容。雖然不能做到百分之百準確,但是至少還是提供了一些方便。

    下文簡單介紹了在我們搜索輸入第一個字符開始,搜索功能執行的流程。

    在SettingsActivity被創建時,SettingsSearchIndexablesProvider也同時被創建出來提供查詢數據.需要查詢的資源通過xmlresources來獲取,SearchIndexableResources裏定義了一個staitic塊,來聲明從哪些xml文件裏獲取查詢條碼的資源。這個數據只在首次創建被初始化一次,初始化後將被插入到數據庫,如果代碼有修改xml資源,需恢復出廠設置重新加載xml資源。

 

public Cursor queryXmlResources(String[] projection) {
        MatrixCursor cursor = new MatrixCursor(INDEXABLES_XML_RES_COLUMNS);
        Collection<SearchIndexableResource> values = SearchIndexableResources.values();
        for (SearchIndexableResource val : values) {
            Object[] ref = new Object[7];
            ref[COLUMN_INDEX_XML_RES_RANK] = val.rank;
            ref[COLUMN_INDEX_XML_RES_RESID] = val.xmlResId;
            ref[COLUMN_INDEX_XML_RES_CLASS_NAME] = val.className;
            ref[COLUMN_INDEX_XML_RES_ICON_RESID] = val.iconResId;
            ref[COLUMN_INDEX_XML_RES_INTENT_ACTION] = null; // intent action
            ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE] = null; // intent target package
            ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS] = null; // intent target class
            cursor.addRow(ref);
        }
        return cursor;
    }


數據庫的創建主要就用到了SettingsSearchIndexablesProviderSearchIndexableResourcesIndexDatabaseHelper這三個類。下面介紹查詢過程。

        查詢的主要界面是在SearchResultsSummary.java這個文件裏來處理的,在oncreate方法裏,我們需要把得到的數據插入到listview裏,搜索建議,處理與搜索結果類似,我們主要看搜索結果的處理:

       mResultsAdapter = newSearchResultsAdapter(getActivity());

        mSuggestionsAdapter =new SuggestionsAdapter(getActivity());

        在輸入第一個字符以後,SearchResultsSummary會執行onQueryTextChange,根據輸入的字符信息,updateSearchResults會被調用來更新搜索結果。因輸入每個字符都自動匹配搜索結果給用戶選擇,所以重新建了UpdateSearchResultsTask(繼承自AsyncTask)這個task來處理搜索匹配。根據輸入的字符信息(mQuery)去search_index.dbIndexDatabaseHelper定義)裏查詢字串信息:

protected Cursor doInBackground(String... params) {

            returnIndex.getInstance(getActivity()).search(params[0]);

        }

 

Search 首先會得到數據庫再進行查詢

  public Cursor search(String query) {
        final SQLiteDatabase database = getReadableDatabase();
        final Cursor[] cursors = new Cursor[2];

        final String primarySql = buildSearchSQL(query, MATCH_COLUMNS_PRIMARY, true);
        Log.d(LOG_TAG, "Search primary query: " + primarySql);
        cursors[0] = database.rawQuery(primarySql, null);

        // We need to use an EXCEPT operator as negate MATCH queries do not work.
        StringBuilder sql = new StringBuilder(
                buildSearchSQL(query, MATCH_COLUMNS_SECONDARY, false));
        sql.append(" EXCEPT ");
        sql.append(primarySql);

        final String secondarySql = sql.toString();
        Log.d(LOG_TAG, "Search secondary query: " + secondarySql);
        cursors[1] = database.rawQuery(secondarySql, null);

        return new MergeCursor(cursors);
    }


然後的事情就由IndexDatabaseHelper來處理:

 

 private SQLiteDatabasegetReadableDatabase() {

        returnIndexDatabaseHelper.getInstance(mContext).getReadableDatabase();

    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章