Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android浮動搜索框的使用

android浮動搜索框的使用

編輯:關於Android編程

引言

在我們的應用程序中經常需要提供搜索服務,比如搜索聯系人, 搜索商品信息等等。我們可以自己在布局中自定義我們的搜索框,實現我們的搜索邏輯。但是還有一種更簡單的方法:使用android系統給我們提供的搜索功能框架。
在android中,提供兩種實現搜索功能的方式:search dialog 和 searchView.
search dialog類似於普通的dialog,懸浮於我們的窗體之上。示例圖如下:
這裡寫圖片描述
searchView通常被嵌套在我們的布局之中,最典型的案例就是在actionBar中使用searchView.下圖是searchView在微信中的使用。(PS:圖中的放大鏡就是searchView)
這裡寫圖片描述

不管你使用哪種方式,安卓系統都會發送查詢請求到處理搜索邏輯的activity中,來實現搜索功能。
另外,除了普通的文字搜索外,還提供了一下的搜索功能:
1.語音搜索
2.最近搜索記錄提示
3.自定義搜索記錄提示
4.google系統搜索框
google系統搜索框vcq9oaM8L3A+DQo8aDIgaWQ9"基本原理">基本原理

首先我們來了解一下系統搜索功能的基本原理。
(一)當用戶在搜索框中執行搜索操作後,系統會自動創建一個Intent,並且將用戶搜索的關鍵字存放到Intent中。
(二)系統會啟動處理搜索邏輯的activity(通常可以命名為SearchableActivity)並將intent傳遞給SearchableActivity,然後在SearchableActivity中處理我們的搜索邏輯。

配置搜索框

第一步,我們需要配置我們搜索框的xml文件,其中包括一些屬性比如:語音搜索,搜索提示和搜索記錄等等。
配置文件通常命名為searchable.xml 並且必須 存放在我們工程的res/xml目錄中(沒有就創建一個)
(PS:系統使用這個配置文件來實例化SearchableInfo對象,這個對象是提供搜索相關的元數據的,比如SearchableActivity的類名,搜索關鍵字的類型等等。但是我們不能自己實例化SearchableInfo 對象,只能通過配置文件的方式來設置)
下面是searchable.xml配置文件的內容

searchable.xml



配置文件的根節點必須是searchable ,其中label是必須的,它的值為一個string資源引用,通常是應用程序的名稱(盡管它是一個必須的屬性,但通常情況下是不顯示出來的,除非你開啟了搜索建議功能)。
android:hint是配置搜索框的輸入提示信息,雖然不是必須的屬性,但是強烈建議設置這個屬性,以便用戶輸入搜索信息的時候,可是知道能輸入那些搜索信息。
以配置很多的屬性,但大部分屬性都只是在使用搜索建議和語音搜索時進行配置。

SearchableActivity

第二步, 我們創建SearchableActivity來處理搜索邏輯並且顯示搜索結果。
我們需要在android-manifest.xml文件中配置SearchableActivity的一些屬性,來將它指定為處理搜索邏輯的activity

android-manifest.xml


    
        
            
        
        
    
    ...

首先在intent-filter節點中添加 ACTION_SEARCH的action。然後再meta-data節點中的name屬性必須為android.app.searchable,resource屬性為我們的配置文件searchable.xml
注意:我們並不需要在intent-filter中配置category,因為SearchManager會根據SearchableActivity的componentName,顯示地傳遞數據給它。
查看下列SearchManager.class的源碼,我們可以知道這是怎麼實現的。

SearchManager.class

 /**
     * Starts the global search activity.
     */
    /* package */ void startGlobalSearch(String initialQuery, boolean selectInitialQuery,
            Bundle appSearchData, Rect sourceBounds) {
            //這是我們的searchableActivity
        ComponentName globalSearchActivity = getGlobalSearchActivity();
        if (globalSearchActivity == null) {
            Log.w(TAG, No global search activity found.);
            return;
        }
        Intent intent = new Intent(INTENT_ACTION_GLOBAL_SEARCH);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        //顯示傳遞
        intent.setComponent(globalSearchActivity);
        // Make sure that we have a Bundle to put source in
        if (appSearchData == null) {
            appSearchData = new Bundle();
        } else {
            appSearchData = new Bundle(appSearchData);
        }
        // Set source to package name of app that starts global search, if not set already.
        if (!appSearchData.containsKey(source)) {
            appSearchData.putString(source, mContext.getPackageName());
        }
        //查詢的數據
        intent.putExtra(APP_DATA, appSearchData);
        if (!TextUtils.isEmpty(initialQuery)) {
            intent.putExtra(QUERY, initialQuery);
        }
        if (selectInitialQuery) {
            intent.putExtra(EXTRA_SELECT_QUERY, selectInitialQuery);
        }
        intent.setSourceBounds(sourceBounds);
        try {
            if (DBG) Log.d(TAG, Starting global search:  + intent.toUri(0));
            mContext.startActivity(intent);
        } catch (ActivityNotFoundException ex) {
            Log.e(TAG, Global search activity not found:  + globalSearchActivity);
        }
    }

一般而言,查詢到的數據都是通過一個ListView來展示的,所以,我們可以讓SearchableActivity繼承ListActivity來方便操作。

在SearchableActivity中,我們需要完成三件事:
1.接受查詢參數
當用戶執行搜索操作的時候,系統通過intent傳遞名為QUERY 的數據,其中包含的就是我們的搜索關鍵字,我們可以在intent中接受QUERY數據

public class SearchActivity extends ListActivity
{
            //測試數據 
    private String[][] datas = { { activity, actionbar, animation, android },
            { bundle, block, bluetooth, boolean } };
            //查詢結果
    private String[] result;
    private Intent intent;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);

    intent = getIntent();
        // 判斷是否是搜索請求
        if (Intent.ACTION_SEARCH.equals(intent.getAction()))
        {
            // 獲取搜索的查詢內容(關鍵字)
            String query = intent.getStringExtra(SearchManager.QUERY);

2.根據查詢參數查詢數據

獲取到查詢關鍵字query後,我們就可以執行我們的查詢邏輯了。

    // 執行相應的查詢動作
            boolean isSuccess =queryContact(query);
private boolean queryContact(String query)
    {
        for (String[] ss : datas)
        {
            for (String s : ss)
            {
                if (s.contains(query)){
                    result = ss;
                    return true;
                }
            }
        }
        return false;
    }

queryContact方法是我寫的模擬查詢字典的方法。這裡可以換成在數據庫或者網絡中查詢數據。

3.顯示查詢到的數據
查詢到數據中,我們需要將數據顯示到ListView中,並且當用戶點擊某一查詢結果時,將查詢結果返回給MainActivity.

intent = new Intent(SearchActivity.this, MainActivity.class);
            if(isSuccess){
                setListAdapter(new ArrayAdapter<>(this,
                        android.R.layout.simple_list_item_1, result));
                getListView().setOnItemClickListener( new OnItemClickListener()
                {



                    @Override
                    public void onItemClick(AdapterView parent, View view,
                            int position, long id)
                    {

                        intent.putExtra(name, result[position]);
                        startActivity(intent);
                    }

                });

            }else{
            Toast.makeText(this, 沒有查詢到數據, Toast.LENGTH_SHORT).show();
            startActivity(intent);
            }
        }
    }

使用搜索框

最後,我們就需要在MainActivity中使用我們的搜索框了。由於前面說過,搜索框默認情況下是隱藏的,需要我們自己來調用。在調用之前,我們還需要在manifest文件中進行配置,指定使用searchableActivity.

  
                
        
            
                

                
            
        

在MianActivity的節點中,我們需要配置meta-data節點,name必須指定為android.app.default_searchable,value表示我們的searchableActivity.
如果想將搜索框指定為全局的,在整個application中都能使用,那就將meta-data節點配置在application節點中。

最後,我們在MainActivity中調用搜索框。
由於不同的設備的物理按鍵有很大的差異,有些手機有物理的搜索按鍵,而有些手機是沒有的。所以我們最好自己在activity中通過一個搜索按鈕來顯式的調用搜索框。另外一種方法是,通過手機軟鍵盤上面的搜索按鈕來調用搜索框,這需要在OnCreate()中調用 setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL) .
搜索框是一個懸浮於屏幕上的dialog。它不會對activity棧和生命周期引起任何變化。所以當搜索框出現的時候,沒有任何如onPause()的方法被調用。
通過調用onSearchRequested()方法,我們來激活搜索框。
在MainActivity中,我們點擊button來顯示搜索框,執行搜索後,將獲取到的搜索結果顯示在TextView中。

MainActivity.class

public class MainActivity extends ActionBarActivity
{
    private TextView msg;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        msg=(TextView) findViewById(R.id.msg);

    }
    @Override
    protected void onResume()
    {

        String name =(String) getIntent().getStringExtra(name);
        if(name!=null)
        msg.setText(name);
        super.onResume();
    }
    public void search(View view)
    {
        onSearchRequested();
    }

}

另外,我們也可以重寫onSearchRequested()方法,在搜索的同時做一些其他的操作,比如暫停音樂播放等等。

@Override
public boolean onSearchRequested() {
    pauseMusic();
    return super.onSearchRequested();
}

另外,如果我們需要對查詢關鍵字加一些限制條件的時候,我們可以調用onSearchRequested()發送一些額外的數據給searchableActivity,searchableActivity中進行處理。

@Override
public boolean onSearchRequested() {
//查詢參數
     Bundle appData = new Bundle();
     appData.putBoolean(SearchableActivity.JARGON, true);
     startSearch(null, false, appData, false);
     return true;
 }

當searchableActivity接受到傳遞的查詢參數和關鍵字時,就可以進行查詢操作了。

//通過SearchManager.APP_DATA來提取數據
Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);
if (appData != null) {
    boolean jargon = appData.getBoolean(SearchableActivity.JARGON);
  //下面這一句表示我們可以進行的操作。。。。
  // “select * from ... where word=query and ...=jargon”;
}

注意:我們不能再onSearchRequested()方法外調用startSearch方法,任何操作都必須通過onSearchRequested()來調用。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved