比如某些网页或搜索引擎会把用户搜索过的内容记录下来,当下次输入曾经搜索过的内容也会列出来。来个图,就明白了
保存记录有四种方法:Preferences,files,Databases,Network。这里以Databases 为例,首先搭建个ProvIDer(不会的童鞋可以参考sdk 里的demo:NotePad-记事本)。
先看看目录结构:
Message.java定义一些常量,数据库字段及Uri:
package com.xyz.autocomplete.provIDer;import androID.net.Uri;import androID.provIDer.BaseColumns;public class Message { public static final String AUTHORITY = "com.xyz.auto"; public static final String CONTENT_TYPE = "vnd.androID.cursor.dir/vnd.xyz.auto"; public static final String CONTENT_ITEM_TYPE = "vnd.androID.cursor.item/vnd.xyz.auto"; public static final class Info implements BaseColumns { public static final String table_name = "messages"; public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/messages"); public static final Uri DELETE_ALL_URI = Uri.parse("content://" + AUTHORITY + "/messages/del/all"); public static final String MESSAGE_CONTENT = "message"; public static final String DEFAulT_SORT_ORDER = " message ASC "; }}
DatabaseHelper.java创建数据库及建表:
package com.xyz.autocomplete.provIDer;import androID.content.Context;import androID.database.sqlException;import androID.database.sqlite.sqliteDatabase;import androID.database.sqlite.sqliteOpenHelper;import androID.util.Log;public class DatabaseHelper extends sqliteOpenHelper { public static final String DB_name = "msg.db"; private static final int DB_VERSION = 1; public DatabaseHelper(Context context) { super(context,DB_name,null,DB_VERSION); } @OverrIDe public voID onCreate(sqliteDatabase db) { // Todo auto-generated method stub db.execsql("CREATE table " + Message.Info.table_name + " (" + Message.Info._ID + " INTEGER PRIMARY KEY autoINCREMENT," + Message.Info.MESSAGE_CONTENT + " TEXT);"); } @OverrIDe public voID onUpgrade(sqliteDatabase db,int oldVersion,int newVersion) { // Todo auto-generated method stub db.execsql("DROP table IF EXISTS " + Message.Info.table_name); onCreate(db); }}
AutoprovIDer.java是继承ContentProvIDer对数据库进行插入,删除,查询,更新等 *** 作,本例只需插入,查询,删除表几个 *** 作:
package com.xyz.autocomplete.provIDer;import java.sql.sqlException;import java.util.HashMap;import com.xyz.autocomplete.R;import com.xyz.autocomplete.provIDer.Message.Info;import androID.content.ContentProvIDer;import androID.content.ContentUris;import androID.content.ContentValues;import androID.content.UriMatcher;import androID.database.Cursor;import androID.database.sqlite.sqliteDatabase;import androID.database.sqlite.sqlitequeryBuilder;import androID.net.Uri;import androID.text.TextUtils;import androID.Widget.Toast;public class AutoprovIDer extends ContentProvIDer { private static HashMap<String,String> sInfoProjectionMap; private static final int MESSAGE = 1; private static final int MESSAGE_ID = 2; private static final int DELETE_ALL = 3; private static final UriMatcher sUriMatcher; private DatabaseHelper mOpenHelper; static { sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(Message.AUTHORITY,Info.table_name,MESSAGE); sUriMatcher.addURI(Message.AUTHORITY,Info.table_name + "/#",MESSAGE_ID); sUriMatcher.addURI(Message.AUTHORITY,Info.table_name + "/del/all",DELETE_ALL); sInfoProjectionMap = new HashMap<String,String>(); sInfoProjectionMap.put(Info._ID,Info._ID); sInfoProjectionMap.put(Info.MESSAGE_CONTENT,Info.MESSAGE_CONTENT); } ... @OverrIDe public boolean onCreate() { // Todo auto-generated method stub mOpenHelper = new DatabaseHelper(getContext()); return true; } @OverrIDe public Uri insert(Uri uri,ContentValues values) { // Todo auto-generated method stub if (sUriMatcher.match(uri) != MESSAGE) { throw new IllegalArgumentException("ProvIDer insert() UnkNown URI " + uri); } if (!values.containsKey(Info.MESSAGE_CONTENT)) { values.put(Info.MESSAGE_CONTENT,"default"); } sqliteDatabase db = mOpenHelper.getWritableDatabase(); long rowID = db.insert(Info.table_name,values); if (rowID <= 0) { try { throw new sqlException("Failed to insert row into " + uri); } catch (sqlException e) { // Todo auto-generated catch block e.printstacktrace(); } } Uri retUri = ContentUris.withAppendedID(Info.CONTENT_URI,rowID); getContext().getContentResolver().notifyChange(retUri,null); Toast.makeText( getContext(),getContext().getString(R.string.insert_info) + values.getAsstring(Info.MESSAGE_CONTENT),Toast.LENGTH_SHORT).show(); return retUri; } @OverrIDe public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder) { // Todo auto-generated method stub sqlitequeryBuilder queryBuilder = new sqlitequeryBuilder(); queryBuilder.settables(Info.table_name); switch (sUriMatcher.match(uri)) { case MESSAGE: queryBuilder.setProjectionMap(sInfoProjectionMap); break; case MESSAGE_ID: queryBuilder.setProjectionMap(sInfoProjectionMap); queryBuilder.appenDWhere(Info._ID + " = " + uri.getPathSegments().get(1)); break; default: throw new IllegalArgumentException("ProvIDer query() UnkNown URI " + uri); } sqliteDatabase db = mOpenHelper.getWritableDatabase(); Cursor cursor = queryBuilder.query(db,projection,selection,selectionArgs,sortOrder); cursor.setNotificationUri(getContext().getContentResolver(),uri); return cursor; } @OverrIDe public int delete(Uri uri,String[] selectionArgs) { // Todo auto-generated method stub sqliteDatabase db = mOpenHelper.getWritableDatabase(); int count; switch (sUriMatcher.match(uri)) { ... case DELETE_ALL: db.execsql("DROP table IF EXISTS " + Info.table_name); db.execsql("CREATE table " + Message.Info.table_name + " (" + Message.Info._ID + " INTEGER PRIMARY KEY autoINCREMENT," + Message.Info.MESSAGE_CONTENT + " TEXT);"); return -1; default: throw new IllegalArgumentException("ProvIDer delete() UnkNown URI " + uri); } getContext().getContentResolver().notifyChange(uri,null); return count; } ...}
上面3个文件就把ProvIDer搭建好了,剩下要做的就是把记录集里以autoCompleteTextVIEw输入内容为头(startWith)的记录检索出来并显示出来。autoCompleteTextVIEw有个很重要的属性是androID:completionThreshold,用于表明最小要敲入多少字符才开始显示List filter。autoCompleteTextVIEw要列出内容肯定要给它传一个数据源(记录集),就是通过setAdapter,这个适配器有个要求就是要实现androID.Widget.Filterable 接口,最简单的可以用ArrayAdapter ,如果用它的话,PopupListVIEw样式不怎么好看,自定义适配器,自定义布局就好多了,请看:autoCompleteAdapter.java(参考ArrayAdapter):
package com.xyz.autocomplete;import java.util.ArrayList;import java.util.List;import androID.content.Context;import androID.vIEw.LayoutInflater;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.ArrayAdapter;import androID.Widget.BaseAdapter;import androID.Widget.Filter;import androID.Widget.Filterable;import androID.Widget.ImageVIEw;import androID.Widget.TextVIEw;import androID.Widget.Toast;public class autoCompleteAdapter extends BaseAdapter implements Filterable { private int mLayoutID; private autoFilter mFilter; private Context mContext; private List<String> mData; private List<String> mObjects; private Object mlock = new Object(); public autoCompleteAdapter(Context ctx,int layout,ArrayList<String> data) { mContext = ctx; mLayoutID = layout; mData = data; mObjects = data; } @OverrIDe public int getCount() { // Todo auto-generated method stub return mObjects.size() > 0 ? mObjects.size() + 1 : 0; } @OverrIDe public String getItem(int position) { // Todo auto-generated method stub return position < getCount() - 1 ? mObjects.get(position) : mContext .getString(R.string.clear_info); } @OverrIDe public long getItemID(int position) { // Todo auto-generated method stub return position; } @OverrIDe public VIEw getVIEw(int position,VIEw convertVIEw,VIEwGroup parent) { // Todo auto-generated method stub VIEwHolder holder = new VIEwHolder(); if (convertVIEw == null) { convertVIEw = LayoutInflater.from(mContext).inflate( R.layout.auto_complete_item,null); holder.mshowtext = (TextVIEw) convertVIEw.findVIEwByID(R.ID.item); holder.mIcon = (ImageVIEw) convertVIEw.findVIEwByID(R.ID.icon); convertVIEw.setTag(holder); } else { holder = (VIEwHolder) convertVIEw.getTag(); } if (position == 0) { convertVIEw.setBackgroundResource(R.drawable.item_corner_top); holder.mshowtext.setText(getItem(position)); holder.mIcon.setVisibility(VIEw.GONE); } else if (position == getCount() - 1) { convertVIEw.setBackgroundResource(R.drawable.item_corner_bottom); holder.mshowtext.setText(mContext.getString(R.string.clear_info)); holder.mIcon.setVisibility(VIEw.VISIBLE); } else { convertVIEw.setBackgroundResource(R.drawable.item_corner_shape); holder.mshowtext.setText(getItem(position)); holder.mIcon.setVisibility(VIEw.GONE); } return convertVIEw; } class VIEwHolder { TextVIEw mshowtext; ImageVIEw mIcon; } @OverrIDe public Filter getFilter() { // Todo auto-generated method stub if (mFilter == null) { mFilter = new autoFilter(); } return mFilter; } private class autoFilter extends Filter { @OverrIDe protected FilterResults performFiltering(CharSequence constraint) { // Todo auto-generated method stub FilterResults results = new FilterResults(); if (constraint == null || constraint.length() == 0) { ArrayList<String> List; synchronized (mlock) { List = new ArrayList<String>(mData); } results.values = List; results.count = List.size(); } else { String prefixString = constraint.toString().tolowerCase(); ArrayList<String> values; synchronized (mlock) { values = new ArrayList<String>(mData); } final int count = values.size(); final ArrayList<String> newValues = new ArrayList<String>(); for (int i = 0; i < count; i++) { final String value = values.get(i); final String valueText = value.toString().tolowerCase(); // First match against the whole,non-splitted value if (valueText.startsWith(prefixString)) { newValues.add(value); } else { final String[] words = valueText.split(" "); final int wordCount = words.length; // Start at index 0,in case valueText starts with // space(s) for (int k = 0; k < wordCount; k++) { if (words[k].startsWith(prefixString)) { newValues.add(value); break; } } } } results.values = newValues; results.count = newValues.size(); } return results; } @OverrIDe protected voID publishResults(CharSequence constraint,FilterResults results) { // Todo auto-generated method stub mObjects = (List<String>) results.values; if (results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalIDated(); } } }}
MainActivity.java做的事情是查询数据库,绑定数据源给autoCompleteTextVIEw:
package com.xyz.autocomplete;import java.util.ArrayList;import java.util.List;import com.xyz.autocomplete.provIDer.DatabaseHelper;import com.xyz.autocomplete.provIDer.Message.Info;import androID.app.Activity;import androID.content.AsyncqueryHandler;import androID.content.ContentResolver;import androID.content.ContentValues;import androID.content.Context;import androID.database.ContentObserver;import androID.database.Cursor;import androID.net.Uri;import androID.os.Bundle;import androID.os.Handler;import androID.text.TextUtils;import androID.util.Log;import androID.vIEw.KeyEvent;import androID.vIEw.VIEw;import androID.vIEw.VIEw.OnClickListener;import androID.Widget.AdapterVIEw;import androID.Widget.AdapterVIEw.OnItemClickListener;import androID.Widget.ArrayAdapter;import androID.Widget.autoCompleteTextVIEw;import androID.Widget.button;import androID.Widget.EditText;import androID.Widget.TextVIEw;import androID.Widget.Toast;public class MainActivity extends Activity implements OnClickListener,OnItemClickListener { private EditText minputText; private button mBtn; private autoCompleteTextVIEw mautoCompleteVIEw; private static final int query_auto_TOKEN = 100; private ArrayList<String> mData = new ArrayList<String>(); private autoCompleteAdapter mautoAdaper = null; private DbChangeResolver mDbChangeResolver; private queryHandler mqueryHandler = null; /** Called when the activity is first created. */ @OverrIDe public voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.main); minputText = (EditText) findVIEwByID(R.ID.input); mBtn = (button) findVIEwByID(R.ID.add); mBtn.setonClickListener(this); mautoCompleteVIEw = (autoCompleteTextVIEw) findVIEwByID(R.ID.auto_complete); mautoCompleteVIEw.setonItemClickListener(this); mautoAdaper = new autoCompleteAdapter(this,R.layout.auto_complete_item,mData); mautoCompleteVIEw.setAdapter(mautoAdaper); mqueryHandler = new queryHandler(getContentResolver()); startquery(); mDbChangeResolver = new DbChangeResolver(new Handler()); getContentResolver().registerContentObserver( Info.CONTENT_URI,true,mDbChangeResolver); } private voID startquery() { mqueryHandler.startquery(query_auto_TOKEN,new Integer(0),Info.CONTENT_URI,new String[] { Info.MESSAGE_CONTENT },Info.DEFAulT_SORT_ORDER); } @OverrIDe public voID onClick(VIEw v) { // Todo auto-generated method stub if (!TextUtils.isEmpty(minputText.getText().toString().trim())) { ContentValues cv = new ContentValues(1); cv.put(Info.MESSAGE_CONTENT,minputText.getText().toString().trim()); getContentResolver().insert(Info.CONTENT_URI,cv); minputText.getText().clear(); } else { Toast.makeText(this,getString(R.string.toast_info),Toast.LENGTH_LONG).show(); } } @OverrIDe public voID onItemClick(AdapterVIEw<?> parent,VIEw vIEw,int position,long ID) { // Todo auto-generated method stub if (position == parent.getCount() - 1) { getContentResolver().delete(Info.DELETE_ALL_URI,null); mautoCompleteVIEw.getText().clear(); mData.clear(); Toast.makeText(this,"所有记录都清除啦",Toast.LENGTH_LONG).show(); } } private class queryHandler extends AsyncqueryHandler { public queryHandler(ContentResolver cr) { super(cr); // Todo auto-generated constructor stub } @OverrIDe protected voID onqueryComplete(int token,Object cookie,Cursor cursor) { if (query_auto_TOKEN == token) { if (cursor == null) { return; } mData.clear(); while (cursor.movetoNext()) { mData.add(cursor.getString(cursor .getColumnIndexOrThrow(Info.MESSAGE_CONTENT))); } mautoAdaper.notifyDataSetChanged(); } } } private class DbChangeResolver extends ContentObserver { private Handler mHandler; public DbChangeResolver(Handler handler) { super(handler); // Todo auto-generated constructor stub mHandler = handler; } @OverrIDe public voID onChange(boolean selfChange) { // Todo auto-generated method stub super.onChange(selfChange); mHandler.removeCallbacks(mDataChangeRunnable); mHandler.postDelayed(mDataChangeRunnable,300); } } private Runnable mDataChangeRunnable = new Runnable() { @OverrIDe public voID run() { // Todo auto-generated method stub startquery(); } };}
过多的就不解释了。
源码下载地址:http://download.csdn.net/detail/zhouyuanjing/5187264
总结以上是内存溢出为你收集整理的AutoCompleteTextView+SQLite实现自动检索全部内容,希望文章能够帮你解决AutoCompleteTextView+SQLite实现自动检索所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)