今天要講的是搜索框應用系列(二),說道搜索框的應用其實並不難,而是在於它的配置非常之繁瑣,對於它的使用主要是方便開發者對於程序中有搜索業務時,更好的設計UI。
今天的應用主要實現的效果是和google搜索一樣,實現聯想功能,如用戶輸入a,列表中則顯示以a開頭的數據庫中的信息。下面是實現的效果圖:
圖(一) 圖(二)
圖(三)
圖(一):當運行項目時,首先出現的界面,該界面簡單,就一個Button和TextView,當單擊button按鈕時,會跳轉到圖(二);
圖(二):進行相關信息的搜索,為用戶提供搜索服務,輸入信息,然后就會跳轉到圖(三);
圖(三):用於顯示搜索出得信息。
實現過程如下:
- 實現過程主要是添加所有的數據到數據庫中。
- 調用搜索控件。
- 根據用戶輸入的信息顯示聯想的所有詞的列表。
- 根據用戶選擇,顯示相應的結果。
下面來詳細的開發本項目。
1、創建一個Android項目,命名為SearchManager。
2、新建一個位於res/xml下的一個searchable.xml(該文件名稱可以改動,不一定非要用這個,我試過!)的配置文件,文件內容具體如下:
- <?xml version="1.0" encoding="utf-8"?>
- <searchable xmlns:android="http://schemas.android.com/apk/res/android"
- android:label="@string/search_label"
- android:searchSuggestAuthority="search"
- android:searchSuggestIntentAction="android.intent.action.VIEW"
- />
3、在layout文件夾下新建一個文件,為result.xml具體內容和main.xml的代碼如下:
main.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@drawable/hao">
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="測試一下搜索" />
- <Button
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:id="@+id/button"
- android:text="搜索" />
- </LinearLayout>
result.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@drawable/hao">
- <TextView
- android:layout_width="fill_parent"
- android:id="@+id/test"
- android:layout_height="wrap_content"
- android:text="搜索結果" />
- </LinearLayout>
4、修改value文件夾下的string.xml代碼,內容如下:
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string name="hello">Hello World, SearchActivty!</string>
- <string name="app_name">Search</string>
- <string name="search_label">xxxs</string>
- <string name="settings_description">Definitions of words</string>
- <string name="search_invoke">sss</string>
- <string name="search_query_results">ssdsadws</string>
- </resources>
5、向drawable-mdpi文件夾中導入一張背景圖片,該圖片可以任意!在這里我就不說了。
6、修改主Activity,SearchActivity.java內容代碼如下:
- public class SearchActivity extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //獲取Intent對象
- Intent intent = this.getIntent();
- //布局
- setContentView(R.layout.main);
- //判斷intent的action是否等於action-view
- if (Intent.ACTION_VIEW.equals(intent.getAction())) {
- SearchUtil.Word theWord = SearchUtil.getInstance().getMatches(
- intent.getDataString().trim().toLowerCase()).get(0);
- launchWord(theWord);
- finish();
- } else {
- //取得按鈕對象
- Button button = (Button) findViewById(R.id.button);
- //注冊按鈕單擊事件
- button.setOnTouchListener(new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- onSearchRequested();
- return false;
- }
- });
- }
- }
- //存儲值,進行界面跳轉
- private void launchWord(SearchUtil.Word pavilion) {
- Intent next = new Intent();
- next.setClass(this, ResultActivty.class);
- Bundle bundle = new Bundle();
- bundle.putString("word", pavilion.word);
- next.putExtras(bundle);
- next.putExtras(bundle);
- startActivity(next);
- }
- }
7、新建一個Activity,我們命名為ResultActivity.java用於顯示搜索結果,該文件的內容代碼如下:
- public class ResultActivty extends Activity{
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.result);
- //取得bundle對象
- Bundle bundle = this.getIntent().getExtras();
- //取得bundle中的信息
- String word = bundle.getString("word");
- //獲取textView對象
- TextView textView=(TextView)findViewById(R.id.test);
- //把該信息顯示在textView中
- textView.setText("搜索結果:"+word);
- }
- }
8、新建一個類SearchProvider,該類繼承了ContentProvider,用於數據存儲和查詢,具體代碼如下:
- public class SearchProvider extends ContentProvider {
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- return 0;
- }
- @Override
- public String getType(Uri uri) {
- return null;
- }
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- return null;
- }
- @Override
- public boolean onCreate() {
- // 添加所有的數據
- SearchUtil.getInstance().ensureLoaded();
- return true;
- }
- @Override
- public Cursor query(Uri uri, String[] projection, String selection,
- String[] selectionArgs, String sortOrder) {
- String query = null;
- if (uri.getPathSegments().size() > 1) {
- query = uri.getLastPathSegment().toLowerCase();
- }
- return getSuggestions(query);
- }
- private Cursor getSuggestions(String query) {
- String processedQuery = query == null ? "" : query.toLowerCase();
- List<SearchUtil.Word> words = SearchUtil.getInstance().getMatches(
- processedQuery);
- MatrixCursor cursor = new MatrixCursor(COLUMNS);
- long id = 0;
- for (SearchUtil.Word word : words) {
- cursor.addRow(columnValuesOfWord(id++, word));
- }
- return cursor;
- }
- private Object[] columnValuesOfWord(long id, SearchUtil.Word word) {
- return new Object[] { id, // _id
- word.word, // text1
- word.definition, // text2
- word.word, // intent_data (included when clicking on item)
- };
- }
- private static final String[] COLUMNS = { "_id",
- SearchManager.SUGGEST_COLUMN_TEXT_1,
- SearchManager.SUGGEST_COLUMN_TEXT_2,
- SearchManager.SUGGEST_COLUMN_INTENT_DATA,// 數據傳遞到intenter中
- };
- @Override
- public int update(Uri uri, ContentValues values, String selection,
- String[] selectionArgs) {
- return 0;
- }
- }
9、新建一個SearchUtil類,便於管理,相關代碼具體如下:
- public class SearchUtil {
- public static class Word {
- public final String word;
- public final String definition;
- public Word(String word, String definition) {
- this.word = word;
- this.definition = definition;
- }
- }
- private static final SearchUtil sInstance = new SearchUtil();
- private final Map<String, List<Word>> mDict = new ConcurrentHashMap<String, List<Word>>();
- public static SearchUtil getInstance() {
- return sInstance;
- }
- private SearchUtil() {
- }
- private boolean mLoaded = false;
- public synchronized void ensureLoaded() {
- if (mLoaded) return;
- new Thread(new Runnable() {
- public void run() {
- //插入數據
- addWord("a", "aaa");
- addWord("aa", "aaa");
- addWord("aaa", "aaa");
- }
- }).start();
- }
- @SuppressWarnings("unchecked")
- public List<Word> getMatches(String query) {
- List<Word> list = mDict.get(query);
- return list == null ? Collections.EMPTY_LIST : list;
- }
- private void addWord(String word, String definition) {
- final Word theWord = new Word(word, definition);
- final int len = word.length();
- for (int i = 0; i < len; i++) {
- final String prefix = word.substring(0, len - i);
- addMatch(prefix, theWord);
- }
- }
- private void addMatch(String query, Word word) {
- List<Word> matches = mDict.get(query);
- if (matches == null) {
- matches = new ArrayList<Word>();
- mDict.put(query, matches);
- }
- matches.add(word);
- }
- }
10、就是相關搜索的配置了,這里需要注意!具體代碼如下:
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.wyf.wpf"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="8" />
- <application android:icon="@drawable/skey" android:label="@string/app_name">
- <activity android:name=".SearchActivity"
- android:label="@string/app_name">
- <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" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- <!-- 指定上面的searchable.xml文件 -->
- <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" />
- </activity>
- <activity android:name=".ResultActivty" android:label="@string/search_query_results" />
- <!--之前searchable.xml中有一個searchSuggestAuthority的值其實和這里的authorities是相同的,這點葯注意-->
- <provider android:name="SearchProvider" android:authorities="search" android:syncable="false" />
- </application>
- </manifest>
到此,整個項目就開發完畢,單擊運行便會得到以上效果。