package com.netease.nim.uikit.contact.core.model; import android.content.Context; import android.os.AsyncTask; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import com.netease.nim.uikit.UIKitLogTag; import com.netease.nim.uikit.common.ui.liv.LetterIndexView; import com.netease.nim.uikit.common.ui.liv.LivIndex; import com.netease.nim.uikit.common.util.log.LogUtil; import com.netease.nim.uikit.contact.core.item.AbsContactItem; import com.netease.nim.uikit.contact.core.item.ContactItemFilter; import com.netease.nim.uikit.contact.core.model.ContactDataTask.Host; import com.netease.nim.uikit.contact.core.query.IContactDataProvider; import com.netease.nim.uikit.contact.core.query.TextQuery; import com.netease.nim.uikit.contact.core.viewholder.AbsContactViewHolder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 通讯录数据适配器 * <p/> * Created by huangjun on 2015/2/10. */ public class ContactDataAdapter extends BaseAdapter { // // COMPONENTS // private final Context context; private final Map<Integer, Class<? extends AbsContactViewHolder<? extends AbsContactItem>>> viewHolderMap; private final ContactGroupStrategy groupStrategy; private final IContactDataProvider dataProvider; // // DATAS // private AbsContactDataList datas; protected final HashMap<String, Integer> indexes = new HashMap<>(); // // OPTIONS // private ContactItemFilter filter; private ContactItemFilter disableFilter; public ContactDataAdapter(Context context, ContactGroupStrategy groupStrategy, IContactDataProvider dataProvider) { this.context = context; this.groupStrategy = groupStrategy; this.dataProvider = dataProvider; this.viewHolderMap = new HashMap<>(6); } public void addViewHolder(int itemDataType, Class<? extends AbsContactViewHolder<? extends AbsContactItem>> viewHolder) { this.viewHolderMap.put(itemDataType, viewHolder); } public final void setFilter(ContactItemFilter filter) { this.filter = filter; } public final void setDisableFilter(ContactItemFilter disableFilter) { this.disableFilter = disableFilter; } public final LivIndex createLivIndex(ListView lv, LetterIndexView liv, TextView tvHit, ImageView ivBk) { return new LivIndex(lv, liv, tvHit, ivBk, getIndexes()); } // // BaseAdapter // @Override public int getCount() { return datas != null ? datas.getCount() : 0; } @Override public Object getItem(int position) { return datas != null ? datas.getItem(position) : null; } @Override public boolean isEmpty() { return datas != null ? datas.isEmpty() : true; } public final TextQuery getQuery() { return datas != null ? datas.getQuery() : null; } private void updateData(AbsContactDataList datas) { this.datas = datas; updateIndexes(datas.getIndexes()); notifyDataSetChanged(); } @Override public long getItemId(int position) { return 0; } @Override public int getItemViewType(int position) { Object obj = getItem(position); if (obj == null) { return -1; } AbsContactItem item = (AbsContactItem) obj; int type = item.getItemType(); Integer[] types = viewHolderMap.keySet().toArray(new Integer[viewHolderMap.size()]); for (int i = 0; i < types.length; i++) { int itemType = types[i]; if (itemType == type) { return i; } } return -1; } @Override public int getViewTypeCount() { return viewHolderMap.size(); } @Override public View getView(int position, View convertView, ViewGroup parent) { AbsContactItem item = (AbsContactItem) getItem(position); if (item == null) { return null; } AbsContactViewHolder<AbsContactItem> holder = null; try { if (convertView == null || (holder = (AbsContactViewHolder<AbsContactItem>) convertView.getTag()) == null) { holder = (AbsContactViewHolder<AbsContactItem>) viewHolderMap.get(item.getItemType()).newInstance(); if (holder != null) { holder.create(context); } } } catch (Exception e) { e.printStackTrace(); } if (holder == null) { return null; } holder.refresh(this, position, item); convertView = holder.getView(); if (convertView != null) { convertView.setTag(holder); } return convertView; } @Override public boolean isEnabled(int position) { if (disableFilter != null) { return !disableFilter.filter((AbsContactItem) getItem(position)); } return true; } // // LOAD // public final void query(String query) { startTask(new TextQuery(query), true); } public final boolean load(boolean reload) { if (!reload && !isEmpty()) { return false; } LogUtil.i(UIKitLogTag.CONTACT, "contact load data"); startTask(null, false); return true; } public final void query(TextQuery query) { startTask(query, true); } private final List<Task> tasks = new ArrayList<>(); /** * 启动搜索任务 * * @param query 要搜索的信息,填null表示查询所有数据 * @param abort 是否终止:例如搜索的时候,第一个搜索词还未搜索完成,第二个搜索词已生成,那么取消之前的搜索任务 */ private void startTask(TextQuery query, boolean abort) { if (abort) { for (Task task : tasks) { task.cancel(false); // 设为true有风险! } } Task task = new Task(new ContactDataTask(query, dataProvider, filter) { @Override protected void onPreProvide(AbsContactDataList datas) { List<? extends AbsContactItem> itemsND = onNonDataItems(); if (itemsND != null) { for (AbsContactItem item : itemsND) { datas.add(item); } } } }); tasks.add(task); task.execute(); } private void onTaskFinish(Task task) { tasks.remove(task); } /** * 搜索/查询数据异步任务 */ private class Task extends AsyncTask<Void, Object, Void> implements Host { final ContactDataTask task; Task(ContactDataTask task) { task.setHost(this); this.task = task; } // // HOST // @Override public void onData(ContactDataTask task, AbsContactDataList datas, boolean all) { publishProgress(datas, all); } @Override public boolean isCancelled(ContactDataTask task) { return isCancelled(); } // // AsyncTask // @Override protected void onPreExecute() { onPreReady(); } @Override protected Void doInBackground(Void... params) { task.run(new ContactDataList(groupStrategy)); return null; } @Override protected void onProgressUpdate(Object... values) { AbsContactDataList datas = (AbsContactDataList) values[0]; boolean all = (Boolean) values[1]; onPostLoad(datas.isEmpty(), datas.getQueryText(), all); updateData(datas); } @Override protected void onPostExecute(Void result) { onTaskFinish(this); } @Override protected void onCancelled() { onTaskFinish(this); } } // // Overrides // /** * 数据未准备 */ protected void onPreReady() { } /** * 数据加载完成 */ protected void onPostLoad(boolean empty, String query, boolean all) { } /** * 加载完成后,加入非数据项 * * @return */ protected List<? extends AbsContactItem> onNonDataItems() { return null; } // // INDEX // private Map<String, Integer> getIndexes() { return this.indexes; } private void updateIndexes(Map<String, Integer> indexes) { // CLEAR this.indexes.clear(); // SET this.indexes.putAll(indexes); } }