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

仿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);
	}
}

保存数据库代码就不上传了,直接下载: 点击打开链接


发布了19 篇原创文章 · 获赞 12 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/u014051380/article/details/23170939
今日推荐