您的位置:首页 > 移动开发 > Android开发

Android 仿百度谷歌搜索自动提示框,将搜索记录保存数据库

2014-04-08 11:41 831 查看
仿Google百度搜索输入关键字有下拉列表提示信息关键词,怎么实现的呢?



view_search_list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<ListView
android:id="@+id/list_category"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:cacheColorHint="#00000000"
android:fadingEdge="none"
android:scrollbars="@null" />

</LinearLayout>


activity_search_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="35dip" >

<TextView
android:id="@+id/tv_context"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dip"
android:singleLine="true"
android:text="我的搜索"
android:textColor="#333333"
android:textSize="16sp" />
</RelativeLayout>

<ImageView
android:layout_width="fill_parent"
android:layout_height="1.5dip" />

</LinearLayout>


EditText结果列表类:

package com.pop.windows;

import java.util.ArrayList;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.RelativeLayout.LayoutParams;

public class AutoCompleteTextView extends EditText {

Context context = null;
MyTextWatcher myTextWatcher = null;
public AutoCompleteTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
setPopw();
this.addTextChangedListener(watcher);
}

/**
* 设置要将试图加进去的父布局
*
* @param layout
*            只能是Relative父布局,如果是linear请用另一个方法
*/
public void setFatherRelativeLayouyt(RelativeLayout layout) {
this.relativeLayout = layout;
isRLayout = true;
}

/**
* 设置要将试图加进去的父布局
*
* @param layout
*            只能是Linear父布局,如果是Relative请用另一个方法
*/
public void setFatherLinearLayout(LinearLayout layout) {
this.linearLayout = layout;
isRLayout = false;
}

/**
* 设置下拉内容的文字库
*
* @param list
*/
public void setMemoryData(ArrayList<String> list) {
this.memoryData = list;
}
/**
* 如果要对此输入框添加TextWatch监听,请使用此方法,不要用系统的
*
* @param myTextWatcher
*/
public void addMyTextWatcher(MyTextWatcher myTextWatcher) {
this.myTextWatcher = myTextWatcher;
}

public void removeMyTextWatcher() {
this.myTextWatcher = null;
}
/**
* 手动隐藏掉这个下拉提示
*/
public void removeTheShowView() {
if (popView.isShown()) {
if (isRLayout) {
relativeLayout.removeView(popView);
} else {
linearLayout.removeView(popView);
}
}
}

public boolean isListShowing() {
return popView.isShown();
}
TextWatcher watcher = new TextWatcher() {

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mList.clear();
mList.addAll(getSimilarString(String.valueOf(s), memoryData));
if (mList.size() > 0) {
mAdapter.notifyDataSetInvalidated();
if (!popView.isShown()) {
int[] top = new int[2];
AutoCompleteTextView.this.getLocationInWindow(top);
// 显示位置稍有不和,可自行修改,这里我就偷懒了
layoutParams.topMargin = top[1] - 15;
layoutParams.leftMargin = top[0];
if (isRLayout) {
relativeLayout.addView(popView, layoutParams);
} else {
linearLayout.addView(popView, layoutParams);
}
popView.setFocusable(true);
}
} else {
if (isRLayout) {
relativeLayout.removeView(popView);
} else {
linearLayout.removeView(popView);
}
}
if (myTextWatcher != null) {
myTextWatcher.onTextChanged(s, start, before, count);
}
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (myTextWatcher != null) {
myTextWatcher.beforeTextChanged(s, start, count, after);
}
}

@Override
public void afterTextChanged(Editable s) {
if (s.length() == 0) {
removeTheShowView();
}
if (myTextWatcher != null) {
myTextWatcher.afterTextChanged(s);
}
}
};

ArrayList<String> memoryData = null;
LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
private View popView = null;
private ListView mlistView = null;
private ArrayList<String> mList = null;
// popw的listview的适配器
private ArrayAdapter<String> mAdapter = null;
RelativeLayout relativeLayout = null;
LinearLayout linearLayout = null;
private boolean isRLayout = false;

private void setPopw() {
if (this.popView == null) {
popView = View.inflate(context, R.layout.view_search_list, null);
}
if (mlistView == null) {
mlistView = (ListView) popView.findViewById(R.id.list_category);
mlistView.setItemsCanFocus(true);
mlistView.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
AutoCompleteTextView.this.setText(mList.get(position));
/*
* 这里是点击列表条目事件,点击可执行直接搜索
*/
// Toast.makeText(context, mList.get(position),
// Toast.LENGTH_LONG).show();
if (isRLayout) {
relativeLayout.removeView(popView);
} else {
linearLayout.removeView(popView);
}
}
});
}
mList = new ArrayList<String>();
if (mAdapter == null) {
mAdapter = new ArrayAdapter<String>(context, R.layout.activity_search_item, R.id.tv_context, mList);
}
mlistView.setAdapter(mAdapter);
}

/**
* 从某字符集合中获取前部分字符串相似的字符集合
* <p>
* 比如,基准字符串为asd的时候,从集合里取出全部以asd打头的字符串
*
* @param edt
*            拿来比较的基准字符
* @param datas
*            字符集和
* @return 匹配的字符集合
*/
private ArrayList<String> getSimilarString(String edt, ArrayList<String> datas) {
ArrayList<String> similars = new ArrayList<String>();
if (datas != null) {
for (String s : datas) {
if (s.startsWith(edt)) {
similars.add(s);
}
}
}
return similars;
}
/**
* 因为控件内部已经做了此系统接口的实现监听,这个接口是自己做的留给外部调用的
* <p>
* 触发机制、字段都和系统自带的一样,就不赘述了
*
* @author hz
*
*/
public interface MyTextWatcher {
/**
*
* @param s
* @param start
* @param before
* @param count
*/
public void onTextChanged(CharSequence s, int start, int before, int count);
public void beforeTextChanged(CharSequence s, int start, int count, int after);
public void afterTextChanged(Editable s);
}
}


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_search"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<com.pop.windows.AutoCompleteTextView
android:id="@+id/btn"
android:layout_width="250dip"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants" />

<Button
android:id="@+id/bt_sousuo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="搜索" />
</LinearLayout>

</LinearLayout>


搜索界面:

package com.pop.windows;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.LinearLayout;

public class MainActivity extends Activity {

private AutoCompleteTextView search_et;
MyHandler mHandler = null;
private static final int UPDATE_VIEW = 1001;
private static final int CHANGE_INPUT = 1002;
private ArrayList<String> data;
private DBManager mgr;
private List<SearchHistoryVo> list;
private LinearLayout ll_search;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
search_et = (AutoCompleteTextView) findViewById(R.id.btn);
ll_search = (LinearLayout) findViewById(R.id.ll_search);
mgr = new DBManager(this);
mHandler = new MyHandler();
data = new ArrayList<String>();
data = getData();
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
data.add(list.get(i).getContent());
}
}
search_et.setFatherLinearLayout(ll_search);
mHandler.sendEmptyMessage(CHANGE_INPUT);

search_et.addTextChangedListener(new TextWatcher() {

@Override
public void afterTextChanged(Editable s) {
mHandler.sendEmptyMessage(CHANGE_INPUT);
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
mHandler.sendEmptyMessage(CHANGE_INPUT);
}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mHandler.sendEmptyMessage(CHANGE_INPUT);
}
});

}

class MyHandler extends Handler {

@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_VIEW : // 更新搜索记录列表
break;
case CHANGE_INPUT :
initData();
break;
}
}
}

public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_sousuo :
btn_search();
search_et.setText("");
break;
}
}
// 添加搜索到数据库中
private void btn_search() {
if (!search_et.getText().toString().trim().equals("")) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SearchHistoryVo item = new SearchHistoryVo();
item.content = search_et.getText().toString();
item.searchtime = sdf.format(new Date());
mgr.addSearchResult(item); // 将搜索记录添加到SQLite中
mHandler.sendEmptyMessage(CHANGE_INPUT);
}
}

// 获得搜索记录数据
private ArrayList<String> getData() {
data.clear();
list = mgr.querySearchHistory();
Collections.reverse(list); // 使用该方法使结果倒序显示
for (int i = 0; i < list.size(); i++) {
data.add(list.get(i).content);
}
return data;
}

// 加载数据
private void initData() {
data = getData();
search_et.setMemoryData(data);
}
}


保存数据库代码就不上传了,直接下载:点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐