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

0 0
原创粉丝点击