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