詳細解讀Android中的搜索框(一)—— 簡單小例子


 

這次開的是一個講解SearchView的欄目,第一篇主要是給一個小例子,讓大家對這個搜索視圖有一個了解,之后再分布細化來說。

 

目標:

我們先來定個目標,我們通過搜索框來輸入要搜索的聯系人名字,輸入的時候下面的listview就展現出候選的人。

 

思路:

1.要得到聯系人數據,就需要有訪問聯系人的權限

2.必須通過ContentResolver來得到操作聯系人名單的指針

3.每次輸入一個字的時候就應該觸發一次搜索,並且能將搜索的結果展示出來

4.既然要進行搜索,那么就要用到SQL語句

 

實現:

1. xml布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <SearchView
        android:id="@+id/search"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#F0F0F0F0" >
    </SearchView>

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:transcriptMode="normal"
        android:layout_below="@id/search"/>

</RelativeLayout>

我們看到listview放在了searchview的下面,這個searchview在高版本api中才提供,如果是想要兼容低版本的話,需要用support包中的控件,使用方式完全一致,但個人覺得在2015年了,沒必要兼容2.x版本的系統了。

 

2. 在manifest(清單)中對activity進行設定

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.kale.searchview"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.READ_CONTACTS"/>  
    
    <uses-sdk
        android:minSdkVersion="11"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" 
            android:windowSoftInputMode = "adjustPan">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>  
                <action android:name="android.intent.action.SEARCH" />  
            </intent-filter>  
  
            <meta-data  
                android:name="android.app.searchable"  
                android:resource="@xml/searchable" />  
        </activity>
    </application>

</manifest>

 

主要的代碼片段:

    <activity
            android:windowSoftInputMode = "adjustPan">
       ……
            <intent-filter>  
                <action android:name="android.intent.action.SEARCH" />  
            </intent-filter>  
  
            <meta-data  
                android:name="android.app.searchable"  
                android:resource="@xml/searchable" />  
        </activity>

這里設定了activity的輸入法模式,用的是不擠壓窗口的模式,這個在之后的文章中會說道,現在只需要知道這個模式會讓輸入法彈出時,不會擠壓activity窗體就行。然后我們定義了過濾器,寫了一個action,這是用search必須的。最后是寫一個xml文件,用來描述searchview的行為。

 

3. 配置搜索模式

res/xml/searchable.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- 配置搜索模式 -->
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="contactsList"
    android:hint="@string/search_hint"
    android:searchMode="queryRewriteFromText" />

 

4.java代碼

4.1 產生可以操作聯系人對象的指針,並且通過它構建listview的適配器

這段代碼先產生指針對象,然后初始化listview的適配器,這樣listview默認就能展示聯系人的名字數據了。然后我優化了操作,讓listview在滑動時隱藏軟鍵盤,這個代碼寫的比較簡陋,在實際運用時需要多多優化。不錯意思已經達到了。

// 得到聯系人名單的指針
        mCursor = getContentResolver().query(RawContacts.CONTENT_URI, PROJECTION, null, null, null);
        // 通過傳入mCursor,將聯系人名字放入listView中。
        mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, mCursor,
                new String[] { RawContacts.DISPLAY_NAME_PRIMARY }, new int[] { android.R.id.text1 }, 0);

        mListView = (ListView) findViewById(android.R.id.list);
        mListView.setAdapter(mAdapter);
        mListView.setOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                // TODO 自動生成的方法存根
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null) {
                    imm.hideSoftInputFromWindow(mListView.getWindowToken(), 0); // 輸入法如果是顯示狀態,那么就隱藏輸入法
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                
            }
        });

 

4.2 找到searchView對象,並進行設定

這里的設定就是設定一些焦點啥的,沒啥可說的。具體在使用時自行調整吧

  mSearchView = (SearchView) findViewById(R.id.search);
        mSearchView.setIconifiedByDefault(true);
        mSearchView.onActionViewExpanded();// 寫上此句后searchView初始是可以點擊輸入的狀態,如果不寫,那么就需要點擊下放大鏡,才能出現輸入框
        mSearchView.setFocusable(false);// 是否獲取焦點
        mSearchView.clearFocus();
        // mSearchView.setIconifiedByDefault(true);

 

4.3 給searchview綁定監聽器(重要)

searchview有一個重要的監聽器,它可以在searchView中文字改變或者是用戶提交搜索時觸發。

mSearchView.setOnQueryTextListener(new OnQueryTextListener() {

            private String TAG = getClass().getSimpleName();

            /*
             * 在輸入時觸發的方法,當字符真正顯示到searchView中才觸發,像是拼音,在舒服法組詞的時候不會觸發
             * 
             * @param queryText
             * 
             * @return false if the SearchView should perform the default action
             * of showing any suggestions if available, true if the action was
             * handled by the listener.
             */
            @Override
            public boolean onQueryTextChange(String queryText) {
                Log.d(TAG, "onQueryTextChange = " + queryText);

               // TODO:當searchview中文字改變時進行的操作
                return true;
            }

            /*
             * 輸入完成后,提交時觸發的方法,一般情況是點擊輸入法中的搜索按鈕才會觸發。表示現在正式提交了
             * 
             * @param queryText
             * 
             * @return true to indicate that it has handled the submit request.
             * Otherwise return false to let the SearchView handle the
             * submission by launching any associated intent.
             */
            @Override
            public boolean onQueryTextSubmit(String queryText) {
                Log.d(TAG, "onQueryTextSubmit = " + queryText);

                // TODO:當用戶提交搜索結果時,需要進行的操作return true;
            }
        });

 

4.4 在監聽器中進行我們需要的處理

我們現在可以針對不同的事件進行不同的處理了,在用戶輸入時要不斷的查詢聯系人,這個查詢的時間很快,所以不用做異步。查詢到結果后顯示到listview中,也就是跟新下適配器的數據。當用戶提交后,隱藏軟鍵盤,開始搜索。之后的操作就沒去做了^_^

mSearchView.setOnQueryTextListener(new OnQueryTextListener() {

            private String TAG = getClass().getSimpleName();

            /*
             * 在輸入時觸發的方法,當字符真正顯示到searchView中才觸發,像是拼音,在舒服法組詞的時候不會觸發
             * 
             * @param queryText
             * 
             * @return false if the SearchView should perform the default action
             * of showing any suggestions if available, true if the action was
             * handled by the listener.
             */
            @Override
            public boolean onQueryTextChange(String queryText) {
                Log.d(TAG, "onQueryTextChange = " + queryText);

                String selection = RawContacts.DISPLAY_NAME_PRIMARY + " LIKE '%" + queryText + "%' " + " OR "
                        + RawContacts.SORT_KEY_PRIMARY + " LIKE '%" + queryText + "%' ";
                // String[] selectionArg = { queryText };
                mCursor = getContentResolver().query(RawContacts.CONTENT_URI, PROJECTION, selection, null, null);
                mAdapter.swapCursor(mCursor); // 交換指針,展示新的數據
                return true;
            }

            /*
             * 輸入完成后,提交時觸發的方法,一般情況是點擊輸入法中的搜索按鈕才會觸發。表示現在正式提交了
             * 
             * @param queryText
             * 
             * @return true to indicate that it has handled the submit request.
             * Otherwise return false to let the SearchView handle the
             * submission by launching any associated intent.
             */
            @Override
            public boolean onQueryTextSubmit(String queryText) {
                Log.d(TAG, "onQueryTextSubmit = " + queryText);

                if (mSearchView != null) {
                    // 得到輸入管理對象
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    if (imm != null) {
                        // 這將讓鍵盤在所有的情況下都被隱藏,但是一般我們在點擊搜索按鈕后,輸入法都會乖乖的自動隱藏的。
                        imm.hideSoftInputFromWindow(mSearchView.getWindowToken(), 0); // 輸入法如果是顯示狀態,那么就隱藏輸入法
                    }
                    mSearchView.clearFocus(); // 不獲取焦點
                }
                return true;
            }
        });

 

 

源碼下載:http://download.csdn.net/detail/shark0017/8362209

 

 

參考自:http://blog.csdn.net/lihenair/article/details/27527827

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM