今天要讲的是搜索框应用系列(二),说道搜索框的应用其实并不难,而是在于它的配置非常之繁琐,对于它的使用主要是方便开发者对于程序中有搜索业务时,更好的设计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>
到此,整个项目就开发完毕,单击运行便会得到以上效果。