我的Android进阶之旅------>Android用AutoCompleteTextView实现搜索历史记录提示

简介: 简介  在我们平常上网的时候经常会用到谷歌或百度,在输入框中输入我们想要输入的信息就会出现其他与其相关的提示信息,非常方便。这种效果在Android中是用AutoCompleteTextView实现的,AutoCompleteTextView是一个可以编辑的文本view,当用户键入时,会自动显示完成建议信息。

简介 

在我们平常上网的时候经常会用到谷歌或百度,在输入框中输入我们想要输入的信息就会出现其他与其相关的提示信息,非常方便。这种效果在Android中是用AutoCompleteTextView实现的, AutoCompleteTextView是一个可以编辑的文本view,当用户键入时,会自动显示完成建议信息。 
建议列表显示在下拉列表框中,可以选中某项代替编辑框里的内容。 
当用户点击回车键时,或者什么也没有选中点击ENTER建时下拉列表会自动消失。 
建议列表是从一个数据适配器获取的数据。  


step1:新建一个项目AutoComplete


step2:设计应用的UI界面   /layout/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"
    >
    <!--  当之有一个EditText或者AutoCompleteTextView的时候,进入画面时是默认得到焦点的。
    	  要想去除焦点,可以在auto之前加一个o像素的layout,并设置他先得到焦点。 -->
    <LinearLayout android:layout_width="0px"  
        android:layout_height="0px" android:focusable="true"  
        android:focusableInTouchMode="true"></LinearLayout>  
    
    <!-- 定义一个自动完成文本框,指定输入一个字符后进行提示 -->
	<AutoCompleteTextView  
		android:id="@+id/auto"
	    android:layout_width="fill_parent" 
	    android:layout_height="wrap_content" 
	    android:hint="请输入文字进行搜索"
	    android:completionHint="最近的5条记录"
	    android:dropDownHorizontalOffset="20dp"
	    android:completionThreshold="1"
	    android:dropDownHeight="fill_parent"/>
	    
	    <!-- 
		android:completionHint            设置出现在下拉菜单中的提示标题
		android:completionThreshold       设置用户至少输入多少个字符才会显示提示
		android:dropDownHorizontalOffset  设置下拉菜单于文本框之间的水平偏移。下拉菜单默认与文本框左对齐
		android:dropDownVerticalOffset    设置下拉菜单于文本框之间的垂直偏移。下拉菜单默认紧跟文本框
 		android:dropDownHeight			     设置下拉菜单的高度
 		android:dropDownWidth			     设置下拉菜单的宽度
 		-->
 	 <Button android:text="搜索" android:id="@+id/search"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"/>  	
</LinearLayout>


step3:MainActivity.java

package cn.roco.autocomplete;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;

public class MainActivity extends Activity {

	private AutoCompleteTextView autoCompleteTextView;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		autoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.auto);
		initAutoComplete("history", autoCompleteTextView);
		Button searchButton = (Button) findViewById(R.id.search);
		searchButton.setOnClickListener(new MyOnClickListener());
	}

	private final class MyOnClickListener implements OnClickListener {
		@Override
		public void onClick(View v) {
			saveHistory("history", autoCompleteTextView);
		}
	}

	/**
	 * 把指定AutoCompleteTextView中内容保存到sharedPreference中指定的字符段
	 * 
	 * @param field
	 *            保存在sharedPreference中的字段名
	 * @param autoCompleteTextView
	 *            要操作的AutoCompleteTextView
	 */
	private void saveHistory(String field,
			AutoCompleteTextView autoCompleteTextView) {
		String text = autoCompleteTextView.getText().toString();
		SharedPreferences sp = getSharedPreferences("network_url", 0);
		String longhistory = sp.getString(field, "nothing");
		if (!longhistory.contains(text + ",")) {
			StringBuilder sb = new StringBuilder(longhistory);
			sb.insert(0, text + ",");
			sp.edit().putString("history", sb.toString()).commit();
		}
	}

	/**
	 * 初始化AutoCompleteTextView,最多显示5项提示,使 AutoCompleteTextView在一开始获得焦点时自动提示
	 * 
	 * @param field
	 *            保存在sharedPreference中的字段名
	 * @param autoCompleteTextView
	 *            要操作的AutoCompleteTextView
	 */
	private void initAutoComplete(String field,
			AutoCompleteTextView autoCompleteTextView) {
		SharedPreferences sp = getSharedPreferences("network_url", 0);
		String longhistory = sp.getString("history", "nothing");
		String[] histories = longhistory.split(",");
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_dropdown_item_1line, histories);
		// 只保留最近的50条的记录
		if (histories.length > 50) {
			String[] newHistories = new String[50];
			System.arraycopy(histories, 0, newHistories, 0, 50);
			adapter = new ArrayAdapter<String>(this,
					android.R.layout.simple_dropdown_item_1line, newHistories);
		}
		autoCompleteTextView.setAdapter(adapter);
		autoCompleteTextView
				.setOnFocusChangeListener(new OnFocusChangeListener() {
					@Override
					public void onFocusChange(View v, boolean hasFocus) {
						AutoCompleteTextView view = (AutoCompleteTextView) v;
						if (hasFocus) {
							view.showDropDown();
						}
					}
				});
	}
}

step4:部署应用到模拟器中


step5:进行几次输入,并点击搜索按钮保存历史记录后,退出应用再重新进入应用


step6:这个时候再进行搜索就会有自动补全的效果:

            



附注:


熟悉android列表开发的话,对于Adapter应该非常熟悉,上面的实例代码,使用了android提供的ArrayAdapter,给予AutoCompleteTextView 绑定数据与视图,我们要定制,首先从这里开始。

 

和其他Adaper一样,ArrayAdapter的基类也是BaseAdapter,我们可以定制自己的Adapter了。


 

可是一运行,木有反应,没有一点提示?

 

的确,我们的视图与数据是绑定了,可是AutoCompleteTextView 却不能根据我们的Adapter获取到合适的数据,因为adapter不符合要求!

 

我们反过来再研究一下ArrayAdapter,它除了是BaseAdapter的子类,它还实现了 Filterable 接口!

 

我们在AutoAdapter中,实现该接口,并返回一个自定义的 Filter

 

 

那个AutoMailFilter又是一个什么样子的类呢?

 

先细细想想 AutoCompleteTextView 是怎样工作的,对,它只是对我们所输入的一些字符,进行过滤、索引,并组成相应的视图反馈给我们的用户,以提高我们的输入效率!

 

那接下来就是构建核心过滤器的时候了,AutoCompleteTextView 只会接收过滤后的数据,所以我们的数据源会多出一份拷贝,一份是原始的,一份则是过滤后的:

 

 

在AutoMailFilter里面,由于继承了,我们必须实现两个重要的方法:

 

protected FilterResults performFiltering(CharSequence prefix) 

在这个方法里面定制过滤策略,根据输入的prefix对数据进行过滤,并组装成FilterResults 结果返回;

 

protected void publishResults(CharSequence constraint, FilterResults results) 

这个方法则是发布结果用的,把上面方法的结果按照一定的要求进行处理后,通知Adapter进行数据视图的刷新

 

总结:

 

按照 AutoCompleteTextView 的工作流程,它依赖两个组件,Adapter 和 Filter,一个是视图的处理,一个是数据过滤处理,对这两个组件进行深度定制,我们就可以随心所欲了。



==================================================================================================

  作者:欧阳鹏  欢迎转载,与人分享是进步的源泉!

  转载请保留原文地址http://blog.csdn.net/ouyang_peng

==================================================================================================


相关文章
|
6月前
|
生物认证 开发工具 Android开发
安卓设备签到,还是用视觉智能平台人脸搜索1:N
安卓设备签到,还是用视觉智能平台人脸搜索1:N
155 2
|
8月前
|
Android开发
Android 中实现模拟搜索的功能详解
Android 中实现模拟搜索的功能详解
59 0
|
4月前
|
Java 测试技术 持续交付
百度搜索:蓝易云【NetMock简介:简化 Java,Android和Kotlin多平台中的HTTP请求测试?】
使用NetMock,您可以在单元测试、集成测试和端到端测试中轻松地模拟和验证HTTP请求和响应,而无需实际发送请求到外部服务。这样可以提高测试的可靠性和可控性,并加快测试执行的速度。无论是在开发过程中还是在持续集成环境中,NetMock都可以帮助您更轻松地进行HTTP请求测试,提高代码质量和稳定性。
41 1
|
7月前
|
编解码 网络协议 Android开发
Android平台RTMP|RTSP直播播放器功能进阶探讨
很多开发者在跟我聊天的时候,经常问我,为什么一个RTMP或RTSP播放器,你们需要设计那么多的接口,真的有必要吗?带着这样的疑惑,我们今天聊聊Android平台RTMP、RTSP播放器常规功能,如软硬解码设置、实时音量调节、实时快照、实时录像、视频view翻转和旋转、画面填充模式设定、解码后YUV、RGB数据回调等:
104 0
|
8月前
|
Android开发
Android 自动补齐文本框AutoCompleteTextView的使用
Android 自动补齐文本框AutoCompleteTextView的使用
34 0
|
8月前
|
Android开发
Android 自定义弹窗 附带搜索过滤功能
前两天要求在项目中添加个小功能,今天正好有时间随手写了一个小demo,过程分享给大家。以后如果有此类需求可直接移植使用。
|
10月前
|
Java 开发工具 Android开发
安卓实战开发之——使用 WIFI 进行设备搜索并获取相应信息
实现使用 WIFI 进行连接设备搜索并获取相应信息的功能案例
147 0
|
11月前
|
Android开发
【Android源码篇】用grep搜索源码内容关键词
精确搜索A关键词,连同A.B也搜出来了。 用这条命令来搜索grep -rwn “ro.build.date” .,但是同时也显示了ro.build.date.utc属性,怎么在搜索的时候把这个多余的属性排除掉?
216 0
|
11月前
|
XML Java Android开发
Android 监听键盘输入(实现搜索、发送、完成等等)
在Android App的实际开发中,时常会需要监听软键盘的输入事件。 所以个人在此进行一个总结。 例如:微信和QQ聊天的消息发送,你会发现他的聊天框并没有发送的控件,软键盘的换行或者某个按钮会变成发送;在某些浏览器的输入框,输入内容后,软件盘的某个按钮会有搜索的字样,还有填写内容时的完成按钮等等,这些都可以通过监听键盘和输入框的一些配置实现这些功能。
|
12月前
|
Web App开发 编解码 前端开发
Android | 音视频方向进阶路线及资源合集
但是系统相机和系统控件VideoView的局限性都是可定制型太差,系统相机的图像分辨率,视频码率以及VideoView的进度条等.
156 0