天天看點

搜尋SearchView

菜單欄添加搜尋功能

  • 布局添加
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_search"
        android:icon="@android:drawable/ic_menu_search"
        android:title="搜尋"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="collapseActionView|ifRoom"/>
</menu>
           
  • 配置
    • xml/searchable.xml

      <?xml version="1.0" encoding="utf-8"?>
      <searchable xmlns:android="http://schemas.android.com/apk/res/android"
                  android:hint="搜尋"
                  android:label="@string/app_name"/>
                 
    • AndroidMainifest.xml

      <manifest package="com.xuie.sharedemo"
                xmlns:android="http://schemas.android.com/apk/res/android">
          ...
          <uses-permission android:name="android.permission.READ_CONTACTS"/>
      
          <application >
              ...
              <activity
                  android:name=".SearchActivity"
                  android:launchMode="singleTop">
                  <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>
                 
  • 加載搜尋功能
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.search, menu);

    MenuItem item = menu.findItem(R.id.action_search);
    searchView = (SearchView) MenuItemCompat.getActionView(item);
    ...
}

...

@Override
protected void onNewIntent(Intent intent) {
    setIntent(intent);
    handleIntent(intent);
}

private void handleIntent(Intent intent) {
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String query = intent.getStringExtra(SearchManager.QUERY);
        ...
    }
}
           

示例

搜尋通訊錄
package xxx;

import android.Manifest;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.SimpleCursorAdapter;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.Toast;

import butterknife.Bind;
import butterknife.ButterKnife;

public class SearchActivity extends AppCompatActivity {
    public static final String TAG = SearchActivity.class.getSimpleName();

    int READ_CONTACTS_REQUEST_CODE = ;

    SearchView searchView;
    SimpleCursorAdapter adapter;
    Cursor cursor;

    final String[] PROJECTION = new String[]{
            ContactsContract.CommonDataKinds.Phone._ID,
            ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY,
            ContactsContract.CommonDataKinds.Phone.NUMBER};

    @Bind(R.id.list_view)
    ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        ButterKnife.bind(this);

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
                != PackageManager.PERMISSION_GRANTED) {
            //申請WRITE_EXTERNAL_STORAGE權限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS},
                    READ_CONTACTS_REQUEST_CODE);
        } else {
            init();
        }
    }

    private void init() {
        cursor = getContentResolver().query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                PROJECTION,
                null,
                null,
                null);

        adapter = new SimpleCursorAdapter(
                this,
                android.R.layout.simple_list_item_2, cursor,
                new String[]{
                        ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY,
                        ContactsContract.CommonDataKinds.Phone.NUMBER
                },
                new int[]{android.R.id.text1, android.R.id.text2},
                );

        listView.setAdapter(adapter);
        listView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                InputMethodManager imm =
                        (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null) {
                    // 輸入法如果是顯示狀态,那麼就隐藏輸入法
                    imm.hideSoftInputFromWindow(listView.getWindowToken(), );
                }
            }

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

    @Override
    public void onRequestPermissionsResult(
            int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        doNext(requestCode, grantResults);
    }

    private void doNext(int requestCode, int[] grantResults) {
        if (requestCode == READ_CONTACTS_REQUEST_CODE) {
            if (grantResults[] == PackageManager.PERMISSION_GRANTED) {
                // Permission Granted
                init();
            } else {
                // Permission Denied
                finish();
            }
        }
    }


    @Override
    protected void onNewIntent(Intent intent) {
        setIntent(intent);
        handleIntent(intent);
    }

    private void handleIntent(Intent intent) {
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);
            doMySearch(query);
        }
    }

    private void doMySearch(String query) {
        Toast.makeText(this, "do search " + query, Toast.LENGTH_SHORT).show();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.search, menu);

        MenuItem item = menu.findItem(R.id.action_search);
        searchView = (SearchView) MenuItemCompat.getActionView(item);

        /*
         * 預設情況下, search widget是"iconified“的,隻是用一個圖示 來表示它(一個放大鏡),
         * 當使用者按下它的時候才顯示search box . 你可以調用setIconifiedByDefault(false)讓search
         * box預設都被顯示。 你也可以調用setIconified()讓它以iconified“的形式顯示。
         */
        searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default
        /*
         * 預設情況下是沒送出搜尋的按鈕,是以使用者必須在鍵盤上按下"enter"鍵來送出搜尋.你可以同過setSubmitButtonEnabled(
         * true)來添加一個送出按鈕("submit" button)
         * 設定true後,右邊會出現一個箭頭按鈕。如果使用者沒有輸入,就不會觸發送出(submit)事件
         */
        searchView.setSubmitButtonEnabled(true);
        /*
         * 初始是否已經是展開的狀态
         * 寫上此句後searchView初始展開的,也就是是可以點選輸入的狀态,如果不寫,那麼就需要點選下放大鏡,才能展開出現輸入框
         */
//        searchView.onActionViewExpanded();
        // 設定search view的背景色
//        searchView.setBackgroundColor(0xff000000);
        /*
         * 預設情況下, search widget是"iconified“的,隻是用一個圖示 來表示它(一個放大鏡),
         * 當使用者按下它的時候才顯示search box . 你可以調用setIconifiedByDefault(false)讓search
         * box預設都被顯示。 你也可以調用setIconified()讓它以iconified“的形式顯示。
         */
        searchView.setIconifiedByDefault(true);
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            /*
             * 在輸入時觸發的方法,當字元真正顯示到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 = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY +
                        " LIKE '%" + queryText + "%' " +
                        " OR "
                        + ContactsContract.CommonDataKinds.Phone.SORT_KEY_PRIMARY +
                        " LIKE '%" + queryText + "%' ";
                // String[] selectionArg = { queryText };
                cursor = getContentResolver().query(
                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        PROJECTION,
                        selection,
                        null,
                        null);

                adapter.swapCursor(cursor); // 交換指針,展示新的資料
                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 (searchView != null) {
                    // 得到輸入管理對象
                    InputMethodManager imm =
                            (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    if (imm != null) {
                        // 這将讓鍵盤在所有的情況下都被隐藏,但是一般我們在點選搜尋按鈕後,輸入法都會乖乖的自動隐藏的。
                        imm.hideSoftInputFromWindow(searchView.getWindowToken(), ); // 輸入法如果是顯示狀态,那麼就隐藏輸入法
                    }
                    searchView.clearFocus(); // 不擷取焦點
                }
                return true;
            }
        });
        return true;
    }
}
           

參考

http://www.cnblogs.com/tianzhijiexian/p/4226675.html

繼續閱讀