BaseActivity.java
package com.elainemomo.activity.base;
....
public abstract class BaseActivity extends FragmentActivity implements OnClickListener {
@Override
protected 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);
@Override
public void onClick(View v) {
processClick(v);//具體點擊事件的處理
}
BaseFragment.java
package com.elainemomo.activity.base;
....
public abstract class BaseFragment extends Fragment implements OnClickListener {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return initView(inflater, container, savedInstanceState);
}
@Override
public 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);
@Override
public 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容器中每一個可以動態滑動的頁面
@Override
public Fragment getItem(int location) {
return fragments.get(location);
}
@Override
public int getCount() {
return fragments.size();
}
}
CursorUtils.java
public class CursorUtils {
public static void printCursor(Cursor cursor){
LogUtils.i(cursor,"1共有"+ 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();
}
}
實例代碼:
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的條目
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return View.inflate(context, R.layout.item_conversation_list, null);
}
//設置listview每一個條目顯示的內容
@Override
public 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){
//如果沒有,就創建1個,并存入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(⑴);
selectedConversationIds.clear();
while(cursor.moveToNext()){
Conversation conversation = Conversation.createFromCursor(cursor);
selectedConversationIds.add(conversation.getThread_id());
}
}
public void cancelAll(){
selectedConversationIds.clear();
notifyDataSetChanged();//界面刷新
}
}
CursorAdapter這個類是繼承于BaseAdapter的它是1個虛類它為Cursor和ListView連接提供了橋梁
繼承CursorAdapter以后,會重寫它的兩個方法:newView()和bindView()
newView():對布局中的View**組件**進行設置
bindView():對獲得的內容進行處理
class ViewHolder{….}內部類中寄存的是初始liste_item中的View參數
然后再設計1個 public ViewHolder getViewHolder(View v)方法來獲得holder
這類組合很經典,以后常常用到。
bean中存儲的是實體類的定義,簡單,但是這次不同點是:
bean中不再寫構造方法,而是使用1個公有靜態的方法,用這個方法去創建實體類,并傳送數據。這主要是可以充分利用到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中必須需要1個_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有兩種情勢,1種是對自定義數據庫查詢,1種是對系統數據庫查詢
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);
public class SimpleAnsyQueryHandler extends AsyncQueryHandler {
public SimpleAnsyQueryHandler(ContentResolver cr) {
super(cr);
}
@Override
protected 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);
}
}
}
使用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;
....
@Override
public boolean onCreate() {
//創建數據庫
helper = GroupOpenHelper.getInstance(getContext());
db = helper.getWritableDatabase();
return false;
}
重寫增刪查改方法:
@Override
public 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);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
switch (matcher.match(uri)) {
case CODE_GROUPS_INSERT:
....
default:
throw new IllegalArgumentException("未辨認uri:"+uri);
}
}
@Override
public 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);
}
}
@Override
public 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);
}
}
注意:這里采取了單例模式
public class GroupOpenHelper extends SQLiteOpenHelper {
/**
* 保證內存中只有1個這樣的數據庫實例,所以使用單例模式
* 單例模式的特點是:構造函數是私有的;私有靜態實例參數;公有靜態的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);
}
@Override
public void onCreate(SQLiteDatabase db) {
//sqlite里面創建表的字段類型中數值型的只有integer,沒有long等類型,而且要注意最后1個字段后面不能添加逗號,否則會報錯
//創建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"
+ ")");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
查詢以后得到的cursor要注意填上1句:cursor.moveToFirst();或cursor.moveTo***,否則結果將不顯現or報錯
BaseDialog.java:
public abstract class BaseDialog extends AlertDialog implements android.view.View.OnClickListener {
protected BaseDialog(Context context) {
super(context,R.style.BaseDialog);
}
@Override
protected 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);
@Override
public 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();
}
@Override
public 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);
}
@Override
public void initData() {
tv_dialog_message.setText(message);
tv_dialog_title.setText(title);
}
@Override
public void initListener() {
bt_dialog_cancel.setOnClickListener(this);
bt_dialog_confirm.setOnClickListener(this);
}
@Override
public 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;
}
@Override
public 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);
}
@Override
public void initData() {
tv_deletemsg_title.setText("正在刪除(0/"+maxProgress+")");
//給進度條設置最大值
pb_deletemsg.setMax(maxProgress);
}
@Override
public void initListener() {
bt_deletemsg_cancel.setOnClickListener(this);
}
@Override
public 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);
//為了顯示軟鍵盤:對話框默許不支持文本輸入,手動把1個輸入框設置為對話框的內容,Android自動對其進行設置
inputDialog.setView(new EditText(context));
inputDialog.show();
}
@Override
public 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);
}
@Override
public void initData() {
tv_inputdialog_title.setText(text);
}
@Override
public void initListener() {
bt_inputdialog_cancel.setOnClickListener(this);
bt_inputdialog_confirm.setOnClickListener(this);
}
@Override
public 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();
}
@Override
public 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);
}
@Override
public void initData() {
tv_dialoglist_title.setText(title);
adapter = new DialogListAdapter();
lv_dialog_list.setAdapter(adapter);
}
@Override
public 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();
}
});
}
@Override
public 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);
}
}
使用FragmentPagerAdapter:
如MainPagerAdapter.java:
public class MainPageAdapter extends FragmentPagerAdapter {
List<Fragment> fragments ;
public MainPageAdapter(FragmentManager fm,List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
// TODO Auto-generated method stub
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
}
然后MainActivity.java再:
....
@Override
public 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();
}
....
注意:selector、shape定義的xml文件是寄存在drawable文件夾下的
實例代碼selector_btn_bg.xml:
<?xml version="1.0" encoding="utf⑻"?>
<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>
實例代碼bg_dialog.xml:
<?xml version="1.0" encoding="utf⑻"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<corners android:radius="8dp"/>
<solid android:color="#ffffff"/>
</shape>
注意:color.xml是寄存在values文件夾下的
實例代碼:
主要介紹: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) {
}
});
例如:AutoSearchAdapter.java 繼承CursorAdapter
public class AutoSearchAdapter extends CursorAdapter {
public AutoSearchAdapter(Context context, Cursor c) {
super(context, c);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return View.inflate(context, R.layout.item_auto_search_lv, null);
}
@Override
public 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);
}
}
@Override
public CharSequence convertToString(Cursor cursor) {
return cursor.getString(cursor.getColumnIndex("data1"));
}
}
NewMsgActivity.java 中關鍵代碼 :
@Override
public 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();
}
這個項目還有缺少對網絡編程、廣播與服務、1些新特性等內容的實例操作,后續項目中注意觸及。
ElaineMOMO源碼地址:https://github.com/ElaineYan489/ElaineMOMO