ElaineMOMO项目总结
来源:互联网 发布:蓝牙分享软件 编辑:程序博客网 时间:2024/05/22 16:46
ElaineMOMO——智能短信 相关技术总结
1、src中的目录结构
- activity.base ————–存放基本activity,方便activity.ui中的activity继承
- activty.ui —————–存放activity
- adapter ——————–存放adapter
- bean ———————-存放实体bean的创建
- dao ————————进行数据库相关的操作包
- dialog———————-对话框
- fragment——————–存放fragment
- globle———————-定义全局变量
- provider——————–存放provider
- receiver——————–存放receiver
- utils———————–存放自定义辅助类or方法
1.2、activity.base 包中关键类与代码说明
activity.base包中包含的类有:
BaseActivity.java
package com.elainemomo.activity.base;....public abstract class BaseActivity extends FragmentActivity implements OnClickListener {@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initView();//初始化布局组件 initData();//初始化数据 initListener();//初始化侦听}public abstract void initView();public abstract void initData();public abstract void initListener();public abstract void processClick(View v);@Overridepublic void onClick(View v) { processClick(v);//具体点击事件的处理}
BaseFragment.java
package com.elainemomo.activity.base; ....public abstract class BaseFragment extends Fragment implements OnClickListener {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return initView(inflater, container, savedInstanceState);}@Overridepublic void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); initData(); initListener();}public abstract View initView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);public abstract void initListener();public abstract void initData();public abstract void processClick(View v);@Overridepublic void onClick(View v) { processClick(v);}}
MainPagerAdapter.java
public class MainPagerAdpter extends FragmentPagerAdapter {List<Fragment> fragments;public MainPagerAdpter(FragmentManager fm,List<Fragment> fragments) { super(fm); this.fragments = fragments;}//返回的fragment会作为viewPager的条目显示出来,就相当于ViewPager容器中每个可以动态滑动的页面@Overridepublic Fragment getItem(int location) { return fragments.get(location);}@Overridepublic int getCount() { return fragments.size();}}
2、utils包中的重点知识
CursorUtils.java
public class CursorUtils {public static void printCursor(Cursor cursor){ LogUtils.i(cursor,"一共有"+ cursor.getCount()+"行"); while(cursor.moveToNext()){ for(int i=0; i<cursor.getColumnCount();i++){ String columnName = cursor.getColumnName(i); String content = cursor.getString(i); LogUtils.i(cursor, columnName+" : "+content); } LogUtils.i(cursor, "==============================="); }}}
LogUtils.java
public class LogUtils {public static boolean isDug = true;public static void i(String tag,String msg){ if(isDug){ Log.i(tag, msg); }}public static void i(Object tag,String msg){ if(isDug){ Log.i(tag.getClass().getSimpleName(), msg); }}public static void e(String tag,String msg){ if(isDug){ Log.i(tag, msg); }}public static void e(Object tag,String msg){ if(isDug){ Log.i(tag.getClass().getSimpleName(), msg); }}}
ToastUtils.java
public class ToastUtils { public static void showToast(Context context,String msg){ Toast.makeText(context, msg, 0).show(); }}
3、数据库知识
实例代码:
public List<Integer> selectedConversationIds = new ArrayList<Integer>();private boolean isSelectMode = false;public boolean isSelectMode() { return isSelectMode;}public void setSelectMode(boolean isSelectMode) { this.isSelectMode = isSelectMode;}public List<Integer> getSelectedConversationIds() { return selectedConversationIds;}public ConversationListAdapter(Context context, Cursor c) { super(context, c); notifyDataSetChanged();//重新刷新界面,数据库改变,前台就会改变}//返回的view对象就是Listview的条目@Overridepublic View newView(Context context, Cursor cursor, ViewGroup parent) { return View.inflate(context, R.layout.item_conversation_list, null);}//设置listview每个条目显示的内容@Overridepublic void bindView(View view, Context context, Cursor cursor) { ViewHolder holder = getHolder(view); Conversation conversation = Conversation.createFromCursor(cursor); if(isSelectMode){ holder.iv_check.setVisibility(View.VISIBLE); if(selectedConversationIds.contains(conversation.getThread_id())){ holder.iv_check.setBackgroundResource(R.drawable.common_checkbox_checked); }else{ holder.iv_check.setBackgroundResource(R.drawable.common_checkbox_normal); } } else{ holder.iv_check.setVisibility(View.GONE); } //设置短信内容 holder.tv_conversation_body.setText(conversation.getSnippet()); String name = ContactDao.getNameByAddress(conversation.getAddress(), context.getContentResolver()); if(TextUtils.isEmpty(name)){ holder.tv_conversation_address.setText(conversation.getAddress()+"("+conversation.getMsg_count()+")"); } else{ holder.tv_conversation_address.setText(name+"("+conversation.getMsg_count()+")"); } //显示时间 if(DateUtils.isToday(conversation.getDate())){ //如果是当前的时间,就显示时分 holder.tv_conversation_date.setText(DateFormat.getTimeFormat(context).format(conversation.getDate())); } else{ //如果不是当前的时间,就显示年月日 holder.tv_conversation_date.setText(DateFormat.getDateFormat(context).format(conversation.getDate())); } //设置头像 Bitmap avatar = ContactDao.getAvatarByAddress(conversation.getAddress(), context.getContentResolver()); if(avatar != null){ holder.iv_conversation_avatar.setBackgroundDrawable(new BitmapDrawable(avatar)); } else{ holder.iv_conversation_avatar.setBackgroundResource(R.drawable.img_default_avatar); }}private ViewHolder getHolder(View view){ //先判断条目view对象中是否有holder ViewHolder holder = (ViewHolder) view.getTag(); if(holder == null){ //如果没有,就创建一个,并存入view对象 holder = new ViewHolder(view); view.setTag(holder); } return holder;}class ViewHolder{ private ImageView iv_conversation_avatar; private TextView tv_conversation_address; private TextView tv_conversation_body; private TextView tv_conversation_date; private ImageView iv_check; //参数就是条目的view对象 public ViewHolder(View view){ iv_conversation_avatar = (ImageView) view.findViewById(R.id.iv_conversation_avatar); tv_conversation_address = (TextView) view.findViewById(R.id.tv_conversation_address); tv_conversation_body = (TextView) view.findViewById(R.id.tv_conversation_body); tv_conversation_date = (TextView) view.findViewById(R.id.tv_conversation_date); iv_check = (ImageView)view.findViewById(R.id.iv_check); }}/** * 把选中的条目存入集合中 * @param position */public void selectSingle(int position){ Cursor cursor = (Cursor) getItem(position); Conversation conversation = Conversation.createFromCursor(cursor); if(selectedConversationIds.contains(conversation.getThread_id())){ selectedConversationIds.remove((Integer)conversation.getThread_id()); } else{ selectedConversationIds.add(conversation.getThread_id()); } notifyDataSetChanged();}public void selectAll(){ Cursor cursor = getCursor(); //因为这里拿到的cursor的索引是随机的,所以要自己先定好位 cursor.moveToPosition(-1); selectedConversationIds.clear(); while(cursor.moveToNext()){ Conversation conversation = Conversation.createFromCursor(cursor); selectedConversationIds.add(conversation.getThread_id()); }}public void cancelAll(){ selectedConversationIds.clear(); notifyDataSetChanged();//界面刷新}}
1、 使用CursorAdapter
CursorAdapter这个类是继承于BaseAdapter的它是一个虚类它为Cursor和ListView连接提供了桥梁
继承CursorAdapter之后,会重写它的两个方法:newView()和bindView()
newView():对布局中的View**组件**进行设置
bindView():对获取的内容进行处理
2、使用ViewHolder内部类
class ViewHolder{….}内部类中存放的是初始liste_item中的View参数
然后再设计一个 public ViewHolder getViewHolder(View v)方法来获取holder
这种组合很经典,以后经常用到。
3、dao操作和bean实体类结合
bean中存储的是实体类的定义,简单,但是这次不同点是:
bean中不再写构造方法,而是使用一个公有静态的方法,用这个方法去创建实体类,并传送数据。这主要是可以充分利用到cursor,如下:
/** * 创建会话bean对象 * @param cursor * @return */public static Conversation createFromCursor(Cursor cursor){ Conversation conversation = new Conversation(); conversation.setSnippet(cursor.getString(cursor.getColumnIndex("snippet"))); conversation.setThread_id(cursor.getInt(cursor.getColumnIndex("_id")));//因为CursorAdapter中必须需要一个_id的标志,才能进行查询 conversation.setMsg_count(cursor.getString(cursor.getColumnIndex("msg_count"))); conversation.setAddress(cursor.getString(cursor.getColumnIndex("address"))); conversation.setDate(cursor.getLong(cursor.getColumnIndex("date"))); return conversation;}
dao包类的操作,就是对数据进行增删查改
这里对查询数据的URI有两种形式,一种是对自定义数据库查询,一种是对系统数据库查询
ElaineMoMo中利用到的系统数据库的URI有:
根据电话号码,查找对于的名字:
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, address);Cursor cursor = resolver.query(uri, new String[]{PhoneLookup.DISPLAY_NAME}, null, null, null);
根据电话号码,查找对于的_id:
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, address); Cursor cursor = resolver.query(uri, new String[]{PhoneLookup._ID}, null, null, null);
获取联系人照片:
//获取联系人照片InputStream is = Contacts.openContactPhotoInputStream(resolver,Uri.withAppendedPath(Contacts.CONTENT_URI, _id));
插入短信内容:
context.getContentResolver().insert(Contant.URI.URI_SMS, values);
4、使用异步查询SimpleAnsyQueryHandler
public class SimpleAnsyQueryHandler extends AsyncQueryHandler {public SimpleAnsyQueryHandler(ContentResolver cr) { super(cr);}@Overrideprotected void onQueryComplete(int token, Object cookie, Cursor cursor) { super.onQueryComplete(token, cookie, cursor);// CursorUtils.printCursor(cursor); if(cookie != null && cookie instanceof CursorAdapter){ ((CursorAdapter)cookie).changeCursor(cursor); }}}
5、使用内容提供者Provider
使用UriMatcher对uri进行匹配
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);{ //uri的匹配规则 //authority为主机名,path为后接的路径,code matcher.addURI(authority, "group/insert", CODE_GROUPS_INSERT); matcher.addURI(authority, "group/query", CODE_GROUPS_QUERY); matcher.addURI(authority, "group/update", CODE_GROUPS_UPDATE); matcher.addURI(authority, "group/delete", CODE_GROUPS_DELETE); ....}
在内容提供者中创建自定义数据库的实例
....GroupOpenHelper helper;private SQLiteDatabase db;....@Overridepublic boolean onCreate() { //创建数据库 helper = GroupOpenHelper.getInstance(getContext()); db = helper.getWritableDatabase(); return false;}
重写增删查改方法:
@Overridepublic Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { switch (matcher.match(uri)) { case CODE_GROUPS_QUERY: Cursor cursor = db.query("groups", projection, selection, selectionArgs, null, null, sortOrder); cursor.setNotificationUri(getContext().getContentResolver(), BASE_URI); return cursor; ... default: throw new IllegalArgumentException("未识别的uri:"+uri); }}@Overridepublic Uri insert(Uri uri, ContentValues values) { switch (matcher.match(uri)) { case CODE_GROUPS_INSERT: .... default: throw new IllegalArgumentException("未识别uri:"+uri); }}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) { switch (matcher.match(uri)) { case CODE_GROUPS_DELETE: int number = db.delete("groups", selection, selectionArgs); getContext().getContentResolver().notifyChange(BASE_URI, null); return number; .... default: throw new IllegalArgumentException("未识别uri:"+uri); }}@Overridepublic int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { switch (matcher.match(uri)) { case CODE_GROUPS_UPDATE: int number = db.update("groups", values, selection, selectionArgs); getContext().getContentResolver().notifyChange(BASE_URI, null); return number; .... default: throw new IllegalArgumentException("未识别uri:"+uri); }}
6、使用SQLiteOpenHelper 创建自定义数据库
注意:这里采用了单例模式
public class GroupOpenHelper extends SQLiteOpenHelper {/** * 保证内存中只有一个这样的数据库实例,所以使用单例模式 * 单例模式的特点是:构造函数是私有的;私有静态实例参数;公有静态的getInstance的方法 */private static GroupOpenHelper instance;public static GroupOpenHelper getInstance(Context context){ if(instance == null){ instance = new GroupOpenHelper(context, "group.db", null, 1); } return instance;}private GroupOpenHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version);}@Overridepublic void onCreate(SQLiteDatabase db) { //sqlite里面创建表的字段类型中数值型的只有integer,没有long等类型,而且要注意最后一个字段后面不能添加逗号,否则会报错 //创建group表 db.execSQL("create table groups(" + "_id integer primary key autoincrement," + "name varchar," + "create_date integer," + "thread_count integer" + ")"); //创建会话和群组的映射表 db.execSQL("create table thread_group(" + "_id integer primary key autoincrement," + "group_id integer," + "thread_id integer" + ")");}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}}
7、数据库操作注意事项
查询之后得到的cursor要注意填上一句:cursor.moveToFirst();或者cursor.moveTo***,否则结果将不呈现or报错
3、Dialog框架包
BaseDialog.java:
public abstract class BaseDialog extends AlertDialog implements android.view.View.OnClickListener {protected BaseDialog(Context context) { super(context,R.style.BaseDialog);}@Overrideprotected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); initView(); initData(); initListener();}public abstract void initView();public abstract void initData();public abstract void initListener();public abstract void processClick(View v);@Overridepublic void onClick(View v) { processClick(v);}}
ConfimDialog.java:
public class ConfimDialog extends BaseDialog {private String title;private String message;private TextView tv_dialog_message;private TextView tv_dialog_title;private Button bt_dialog_cancel;private Button bt_dialog_confirm;private OnConfimListener onConfimListener;public OnConfimListener getOnConfimListener() { return onConfimListener;}public void setOnConfimListener(OnConfimListener onConfimListener) { this.onConfimListener = onConfimListener;}public String getTitle() { return title;}public void setTitle(String title) { this.title = title;}public String getMessage() { return message;}public void setMessage(String message) { this.message = message;}protected ConfimDialog(Context context) { super(context);}public static void showDialog(Context context,String title,String message,OnConfimListener onConfimListener){ ConfimDialog confimDialog = new ConfimDialog(context); confimDialog.setTitle(title); confimDialog.setMessage(message); confimDialog.setOnConfimListener(onConfimListener); confimDialog.show();}@Overridepublic void initView() { setContentView(R.layout.dialog_confim); tv_dialog_message = (TextView) findViewById(R.id.tv_dialog_message); tv_dialog_title = (TextView) findViewById(R.id.tv_dialog_title); bt_dialog_cancel = (Button) findViewById(R.id.bt_dialog_cancel); bt_dialog_confirm = (Button) findViewById(R.id.bt_dialog_confirm);}@Overridepublic void initData() { tv_dialog_message.setText(message); tv_dialog_title.setText(title);}@Overridepublic void initListener() { bt_dialog_cancel.setOnClickListener(this); bt_dialog_confirm.setOnClickListener(this);}@Overridepublic void processClick(View v) { switch (v.getId()) { case R.id.bt_dialog_cancel: if(onConfimListener != null){ onConfimListener.onCancel(); } break; case R.id.bt_dialog_confirm: if(onConfimListener != null){ onConfimListener.onConfim(); } break; default: break; } dismiss();}//设置监听接口public interface OnConfimListener{ void onCancel(); void onConfim();}}
deleteMsgDialog.java:
public class DeleteMsgDialog extends BaseDialog {private TextView tv_deletemsg_title;private ProgressBar pb_deletemsg;private Button bt_deletemsg_cancel;private int maxProgress;private OnDeleteCancelListener onDeleteCancelListener;protected DeleteMsgDialog(Context context,int maxProgress,OnDeleteCancelListener onDeleteCancelListener) { super(context); this.maxProgress = maxProgress; this.onDeleteCancelListener = onDeleteCancelListener;}public static DeleteMsgDialog showDeleteDialog(Context context,int maxProgress,OnDeleteCancelListener onDeleteCancelListener){ DeleteMsgDialog dialog = new DeleteMsgDialog(context, maxProgress, onDeleteCancelListener); dialog.show(); return dialog;}@Overridepublic void initView() { setContentView(R.layout.dialog_delete); tv_deletemsg_title = (TextView) findViewById(R.id.tv_deletemsg_title); pb_deletemsg = (ProgressBar) findViewById(R.id.pb_deletemsg); bt_deletemsg_cancel = (Button) findViewById(R.id.bt_deletemsg_cancel);}@Overridepublic void initData() { tv_deletemsg_title.setText("正在删除(0/"+maxProgress+")"); //给进度条设置最大值 pb_deletemsg.setMax(maxProgress);}@Overridepublic void initListener() { bt_deletemsg_cancel.setOnClickListener(this);}@Overridepublic void processClick(View v) { switch (v.getId()) { case R.id.bt_deletemsg_cancel: if(onDeleteCancelListener != null){ onDeleteCancelListener.onCancel(); } dismiss();//让对话框消失 break; default: break; }}public interface OnDeleteCancelListener{ void onCancel();}/** * 刷新进度条和标题 * @param progress */public void updataProgressAndTitle(int progress){ pb_deletemsg.setProgress(progress); tv_deletemsg_title.setText("正在删除("+progress+"/"+maxProgress);}}
InputDialog.java:
public class InputDialog extends BaseDialog {private String text;private Button bt_inputdialog_confirm;private Button bt_inputdialog_cancel;private EditText et_inputdialog_message;private TextView tv_inputdialog_title;private OnInputDialogListener onInputDialogListener;protected InputDialog(Context context,OnInputDialogListener onInputDialogListener,String text){ super(context); this.onInputDialogListener = onInputDialogListener; this.text = text;}public static void showInputDialog(Context context,OnInputDialogListener onInputDialogListener,String text){ InputDialog inputDialog = new InputDialog(context, onInputDialogListener, text); //为了显示软键盘:对话框默认不支持文本输入,手动把一个输入框设置为对话框的内容,Android自动对其进行设置 inputDialog.setView(new EditText(context)); inputDialog.show();}@Overridepublic void initView() { setContentView(R.layout.dialog_input); tv_inputdialog_title = (TextView) findViewById(R.id.tv_inputdialog_title); et_inputdialog_message = (EditText) findViewById(R.id.et_inputdialog_message); bt_inputdialog_cancel = (Button) findViewById(R.id.bt_inputdialog_cancel); bt_inputdialog_confirm = (Button) findViewById(R.id.bt_inputdialog_confirm);}@Overridepublic void initData() { tv_inputdialog_title.setText(text);}@Overridepublic void initListener() { bt_inputdialog_cancel.setOnClickListener(this); bt_inputdialog_confirm.setOnClickListener(this);}@Overridepublic void processClick(View v) { switch (v.getId()) { case R.id.bt_inputdialog_confirm: if(onInputDialogListener != null){ onInputDialogListener.confim(et_inputdialog_message.getText().toString()); } dismiss(); break; case R.id.bt_inputdialog_cancel: if(onInputDialogListener != null){ onInputDialogListener.cancel(); } dismiss(); default: break; }}public interface OnInputDialogListener{ void cancel(); void confim(String inputMessage );}}
ListDialog.java:
public class ListDialog extends BaseDialog {private String title;private String[] items;private TextView tv_dialoglist_title;private ListView lv_dialog_list;private Context context;private OnClickListener onClickListener;private DialogListAdapter adapter;protected ListDialog(Context context,String title,String[] items,OnClickListener onClickListener) { super(context); this.context = context; this.title = title; this.items = items; this.onClickListener = onClickListener;}public static void showListDialog(Context context,String title,String[] items,OnClickListener onItemClickListener){ ListDialog listDialog = new ListDialog(context, title, items, onItemClickListener); listDialog.show();}@Overridepublic void initView() { setContentView(R.layout.dialog_list); tv_dialoglist_title = (TextView) findViewById(R.id.tv_dialoglist_title); lv_dialog_list = (ListView) findViewById(R.id.lv_dialog_list);}@Overridepublic void initData() { tv_dialoglist_title.setText(title); adapter = new DialogListAdapter(); lv_dialog_list.setAdapter(adapter);}@Overridepublic void initListener() { lv_dialog_list.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if(onClickListener != null){ onClickListener.onClickListener(parent, view, position, id);; } dismiss(); } });}@Overridepublic void processClick(View v) {}class DialogListAdapter extends BaseAdapter{ private TextView tv_dialoglist_item; @Override public int getCount() { // TODO Auto-generated method stub return items.length; } @Override public Object getItem(int position) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = View.inflate(context, R.layout.item_listdialog, null); tv_dialoglist_item = (TextView) view.findViewById(R.id.tv_dialoglist_item); tv_dialoglist_item.setText(items[position]); return view; }}public interface OnClickListener{ void onClickListener(AdapterView<?> parent, View view, int position, long id);}}
4、利用viewPager和Fragment结合,设置页面滑动页面的效果
使用FragmentPagerAdapter:
如MainPagerAdapter.java:
public class MainPageAdapter extends FragmentPagerAdapter {List<Fragment> fragments ;public MainPageAdapter(FragmentManager fm,List<Fragment> fragments) { super(fm); this.fragments = fragments;}@Overridepublic Fragment getItem(int position) { // TODO Auto-generated method stub return fragments.get(position);}@Overridepublic int getCount() { return fragments.size();}}
然后MainActivity.java再:
....@Overridepublic void initData() { fragments = new ArrayList<Fragment>(); ConversationFragment conversationFragment = new ConversationFragment(); GroupFragment groupFragment = new GroupFragment(); SearchFragment searchFragment = new SearchFragment(); fragments.add(conversationFragment); fragments.add(groupFragment); fragments.add(searchFragment); mainPagerAdpter = new MainPagerAdpter(getSupportFragmentManager(), fragments); viewPager.setAdapter(mainPagerAdpter); textLightAndScale(); computeIndicateLineWidth();}....
5、layout布局中的重要内容
5.1 使用selector
注意:selector、shape定义的xml文件是存放在drawable文件夹下的
实例代码selector_btn_bg.xml:
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/bg_btn_pressed" android:state_pressed="true"></item> <item android:drawable="@drawable/bg_btn_normal" android:state_pressed="false"></item></selector>
5.2 使用shape,自定义简单的图片外型
实例代码bg_dialog.xml:
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="8dp"/> <solid android:color="#ffffff"/></shape>
5.3 使用color,自定义颜色改变
注意:color.xml是存放在values文件夹下的
实例代码:
6、监听
主要介绍:EditText中的addTextChangedListener,随着输入的内容实时改变
et_search.addTextChangedListener(new TextWatcher() { //s:EditText中输入的参数 @Override public void onTextChanged(CharSequence s, int start, int before, int count) { simpleAnsyQueryHandler.startQuery(0, adapter, Contant.URI.URI_SMS_CONVERSATION, projection, "body like '%"+s+"%'", null, null); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { } });
7、EditText中动态输入内容,下拉列表中可以动态显示查询的结果,并且下拉列表中的条目可以具备点击事件
例如:AutoSearchAdapter.java 继承CursorAdapter
public class AutoSearchAdapter extends CursorAdapter {public AutoSearchAdapter(Context context, Cursor c) { super(context, c);}@Overridepublic View newView(Context context, Cursor cursor, ViewGroup parent) { return View.inflate(context, R.layout.item_auto_search_lv, null);}@Overridepublic void bindView(View view, Context context, Cursor cursor) { ViewHolder holder = getHolder(view); holder.tv_auto_search_address.setText(cursor.getString(cursor.getColumnIndex("data1"))); holder.tv_auto_search_name.setText(cursor.getString(cursor.getColumnIndex("display_name")));}public ViewHolder getHolder(View view){ ViewHolder holder = (ViewHolder) view.getTag(); if(holder == null){ holder = new ViewHolder(view); view.setTag(holder); } return holder;}class ViewHolder{ private TextView tv_auto_search_address; private TextView tv_auto_search_name; public ViewHolder(View view){ tv_auto_search_address = (TextView) view.findViewById(R.id.tv_auto_search_address); tv_auto_search_name = (TextView) view.findViewById(R.id.tv_auto_search_name); }}@Overridepublic CharSequence convertToString(Cursor cursor) { return cursor.getString(cursor.getColumnIndex("data1"));}}
NewMsgActivity.java 中关键代码 :
@Overridepublic void initData() { adapter = new AutoSearchAdapter(this, null); et_newmsg_address.setAdapter(adapter); adapter.setFilterQueryProvider(new FilterQueryProvider() { @Override public Cursor runQuery(CharSequence constraint) { String[] projection = { "data1", "display_name", "_id" }; //模糊查询 String selection = "data1 like '%" + constraint + "%'"; Cursor cursor = getContentResolver().query(Phone.CONTENT_URI, projection, selection, null, null); CursorUtils.printCursor(cursor); //返回cursor,就是把cursor交给adapter return cursor; } }); initTitleBar();}
8、总结
这个项目还有缺少对网络编程、广播与服务、一些新特性等内容的实例操作,后续项目中注意涉及。
ElaineMOMO源码地址:https://github.com/ElaineYan489/ElaineMOMO
- ElaineMOMO项目总结
- 项目总结
- 项目总结
- 项目总结
- 项目总结
- 项目总结
- 项目总结!!!
- 项目总结
- ××项目总结
- 项目总结
- 项目总结
- 项目总结
- 项目总结
- 项目总结
- 项目总结
- 项目总结
- 项目总结
- 项目总结
- 读者写者问题-写者优先参考答案
- 中文 iOS/Mac 开发博客列表(大
- 解决创建Maven Web项目的时候卡在installing dynamic web module facet的问题
- django admin 密码修改
- 飞速流量压缩仪app v2.2.0官方iphone版
- ElaineMOMO项目总结
- WEB、APP端问题定位测试工具
- .NET程序中加入Autodesk Design Review 2013 ,打包完成后安装提示未注册XXX.dll解决办法
- handler机制原理
- java安全框架-Shiro学习笔记(五)-Shiro集成Web
- Python将list中的string批量转化成int/float
- 创建 admin 后台账号
- JVM运行时的数据区
- Dialog全屏,一行代码搞定