ListView、CursorAdapter的使用
Fragment里面的ListView使用CursorAdapter的案例
Fragment中
@Override
public void initData() {
String[] projection = {
"sms.body AS snippet",
"sms.thread_id AS _id",
"groups.msg_count AS msg_count",
"address AS address",
"date AS date"
};
//创建一个adapter
adapter = new ConversationListAdapter(getActivity(), null);
//设置adapter
lv_conversation.setAdapter(adapter);
/* Cursor cursor = getActivity().getContentResolver().query(Constant.URI.URI_SMS_CONVERSATION, null, null, null, null);
CursorUtils.printCursor(cursor);*/
//异步查询数据
SimpleQueryHandler queryHandler = new SimpleQueryHandler(getActivity().getContentResolver());
//adapter作为携带数据,传进onQueryComplete(int, Object, Cursor)中
queryHandler.startQuery(0, adapter, Constant.URI.URI_SMS_CONVERSATION, projection, null, null, "date desc");
}
SimpleQueryHandler 类:
public class SimpleQueryHandler extends AsyncQueryHandler {
public SimpleQueryHandler(ContentResolver cr) {
super(cr);
}
@Override
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
super.onQueryComplete(token, cookie, cursor);
//每次进入Fragment中都会查询初始化cursor
if (cookie != null && cookie instanceof CursorAdapter) {
((CursorAdapter)cookie).changeCursor(cursor);
}
}
}
ConversationListenerAdapter类:
业务逻辑可不看
public class ConversationListAdapter extends CursorAdapter {
public boolean isSelectMode() {
return isSelectMode;
}
public void setSelectMode(boolean selectMode) {
isSelectMode = selectMode;
}
public List<Integer> getSelectedConversationIds() {
return selectedConversationIds;
}
List<Integer> selectedConversationIds = new ArrayList<>();
private boolean isSelectMode = false;
public ConversationListAdapter(Context context, Cursor c) {
super(context, c);
}
@Override
//填充listview
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return View.inflate(context, R.layout.item_conversation_list, null);
}
@Override
//在已有的item view里面绑定数据
public void bindView(View view, Context context, Cursor cursor) {
//viewholder保存需要的控件
ViewHolder holder = getHolder(view);
Conversation conversation = Conversation.createFromCursor(cursor);
holder.tv_body.setText(conversation.getSnippet());
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);
}
String name = ContactDao.getNameByAddress(context.getContentResolver(), conversation.getAddress());
if (TextUtils.isEmpty(name)) {
holder.tv_address.setText(conversation.getAddress().concat("(").concat(conversation.getMsg_count().concat(")")));
} else {
holder.tv_address.setText(name.concat("(").concat(conversation.getMsg_count().concat(")")));
}
if (DateUtils.isToday(conversation.getDate())) {
holder.tv_date.setText(DateFormat.getTimeFormat(context).format(conversation.getDate()));
} else {
holder.tv_date.setText(DateFormat.getDateFormat(context).format(conversation.getDate()));
}
Bitmap avatar = ContactDao.getAvatarByAddress(context.getContentResolver(), conversation.getAddress());
if (avatar == null) {
holder.iv_avator.setBackgroundResource(R.drawable.img_default_avatar);
} else {
holder.iv_avator.setBackgroundDrawable(new BitmapDrawable(context.getResources(), avatar));
}
}
//这里采用View.setTag来保存holder数据,相当于缓存优化
private ViewHolder getHolder(View view) {
ViewHolder holder = (ViewHolder) view.getTag();
if (holder == null) {
holder = new ViewHolder(view);
view.setTag(holder);
}
return holder;
}
public void selectAll() {
Cursor cuusor = getCursor();
cuusor.moveToPosition(-1);
selectedConversationIds.clear();
while (cuusor.moveToNext()) {
Conversation conversation = Conversation.createFromCursor(cuusor);
selectedConversationIds.add(conversation.getThread_id());
}
// cuusor.close();
notifyDataSetChanged();
}
public void cancelSelect() {
selectedConversationIds.clear();
}
//ViewHolder类
class ViewHolder {
private final ImageView iv_avator;
private final TextView tv_address;
private final TextView tv_body;
private final TextView tv_date;
private final ImageView iv_check;
public ViewHolder(View view) {
iv_avator = (ImageView) view.findViewById(R.id.iv_avator);
iv_check = (ImageView) view.findViewById(R.id.iv_check);
tv_address = (TextView) view.findViewById(R.id.tv_address);
tv_body = (TextView) view.findViewById(R.id.tv_body);
tv_date = (TextView) view.findViewById(R.id.tv_date);
}
}
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();
}
}
上面用到的一些类:
ContactDao类:
执行相关的查询操作
public class ContactDao {
//通过地址及电话号码查询名字
public static String getNameByAddress(ContentResolver contentResolver, String address) {
String name = null;
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, address);
Cursor cursor = contentResolver.query(uri, new String[]{PhoneLookup.DISPLAY_NAME}, null, null, null);
assert cursor != null;
if (cursor.moveToFirst()) {
name = cursor.getString(0);
cursor.close();
}
return name;
}
//通过地址来查询通讯录里面的头像
public static Bitmap getAvatarByAddress(ContentResolver contentResolver, String address) {
Bitmap avatar = null;
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, address);
Cursor cursor = contentResolver.query(uri, new String[]{PhoneLookup._ID}, null, null, null);
assert cursor != null;
if (cursor.moveToFirst()) {
String _id = cursor.getString(0);
InputStream is = ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, _id));
avatar = BitmapFactory.decodeStream(is);
cursor.close();
}
return avatar;
}
}
Conservation类:从指定的cursor构造一个bean,注意没有构造函数,采用静态方法返回对象
public class Conversation {
private String snippet;
private int thread_id;
private String msg_count;
private String address;
private long date;
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")));
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public long getDate() {
return date;
}
public void setDate(long date) {
this.date = date;
}
public String getSnippet() {
return snippet;
}
public void setSnippet(String snippet) {
this.snippet = snippet;
}
public int getThread_id() {
return thread_id;
}
public void setThread_id(int thread_id) {
this.thread_id = thread_id;
}
public String getMsg_count() {
return msg_count;
}
public void setMsg_count(String msg_count) {
this.msg_count = msg_count;
}
}
Fragment中listview设置监听
lv_conversation.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (adapter.isSelectMode()) {
//通过adapter来操作
adapter.selectSingle(position);
} else {
}
}
});
通过adapter来处理监听事件
public void processListener(View view) {
switch (view.getId()) {
case R.id.bt_edit:
showselectMenu();
// System.out.println("监听到事件");
adapter.setSelectMode(true);
//通知界面刷新
adapter.notifyDataSetChanged();
break;
case R.id.bt_conversation_cancel:
showEditMenu();
adapter.setSelectMode(false);
adapter.cancelSelect();
adapter.notifyDataSetChanged();
break;
case R.id.bt_conversation_select:
adapter.selectAll();
break;
case R.id.bt_conversation_delete:
selectedConversationIds = adapter.getSelectedConversationIds();
if (selectedConversationIds.size() == 0)
return;
showDeleteDialog();
break;
}
}
通知数据变化的函数,继承自BaseAdapter
notifyDataSetChanged()
Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.