package com.yuyh.library.view.list.indexablelistview;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.yuyh.library.view.list.indexablelistview.help.PinyinComparator;
import com.yuyh.library.view.list.indexablelistview.help.PinyinUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by YoKeyword on 16/3/20.
*/
public abstract class IndexableAdapter<T extends IndexEntity> extends BaseAdapter {
protected static final int TYPE_CONTENT = -100;
protected static final int TYPE_INDEX = -99;
protected SparseArray<String> mTitleMap = new SparseArray<>();
private List<T> mItems = new ArrayList<>();
private List<T> mFilterList;
private ViewHolder mContentHolder;
private TextView mTvTitle;
private List<String> mHeaderIndexs = new ArrayList<>();
private int mHeaderSize;
private IndexHeaderEntity[] mHeaderEntitied;
private boolean mIsFilter;
private ViewGroup mParentView;
private boolean mNeedShutdown;
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getCount() {
if (mIsFilter) {
return mFilterList.size();
}
return mItems.size() + mTitleMap.size();
}
@Override
public Object getItem(int position) {
if (mIsFilter) {
return mFilterList.get(position);
}
if (mTitleMap.get(position) != null) {
return mTitleMap.get(position);
} else {
return mItems.get(getItemMappingPostion(position));
}
}
@Override
public int getItemViewType(int position) {
if (mIsFilter) {
return TYPE_CONTENT;
}
if (mTitleMap.get(position) != null) {
return TYPE_INDEX;
}
return TYPE_CONTENT;
}
@Override
public int getViewTypeCount() {
if (mIsFilter) {
return 1;
}
return 2;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int type = getItemViewType(position);
if (convertView == null) {
if (type == TYPE_CONTENT) {
mContentHolder = onCreateViewHolder(parent);
convertView = mContentHolder.getItemView();
convertView.setTag(mContentHolder);
} else {
mTvTitle = onCreateTitleViewHolder(parent);
convertView = mTvTitle;
convertView.setTag(mTvTitle);
}
} else {
if (type == TYPE_CONTENT) {
mContentHolder = (ViewHolder) convertView.getTag();
} else {
mTvTitle = (TextView) convertView.getTag();
}
}
if (type == TYPE_CONTENT) {
T item = getRealItem(position);
onBindViewHolder(mContentHolder, item);
} else {
String firstSpell = getIndex(position);
mTvTitle.setText(firstSpell);
}
return convertView;
}
protected abstract TextView onCreateTitleViewHolder(ViewGroup parent);
protected abstract ViewHolder onCreateViewHolder(ViewGroup parent);
protected abstract void onBindViewHolder(ViewHolder holder, T cityEntity);
TextView getTitleTextView() {
if (mTvTitle == null) {
return onCreateTitleViewHolder(mParentView);
}
return mTvTitle;
}
void setParent(ViewGroup viewGroup) {
this.mParentView = viewGroup;
}
protected class ViewHolder {
View itemView;
public ViewHolder(View view) {
itemView = view;
}
View getItemView() {
return itemView;
}
}
void setNeedShutdown(boolean needShutdown) {
mNeedShutdown = needShutdown;
}
boolean isNeedShutdown() {
return mNeedShutdown;
}
void setDatas(final List<T> items, final IndexHeaderEntity... headerEntities) {
mTitleMap.clear();
mHeaderIndexs.clear();
// 给数据源赋值 拼音,首字母
if (processIndexEntity(items)) return;
Collections.sort(items, new PinyinComparator());
mItems = items;
mHeaderEntitied = headerEntities;
// 给headerEntity赋值 拼音
processHeaderEntity(headerEntities);
mHeaderSize = 0;
for (int i = 0; i < headerEntities.length; i++) {
if (mNeedShutdown) return;
IndexHeaderEntity headerEntity = headerEntities[i];
List<T> headerList = headerEntity.getHeaderList();
mTitleMap.put(mHeaderSize, headerEntity.getHeaderTitle());
mItems.addAll(mHeaderSize - i, headerList);
mHeaderSize = mHeaderSize + 1 + headerList.size();
for (T t : headerList) {
if (mNeedShutdown) return;
t.setFirstSpell(headerEntity.getIndex());
}
mHeaderIndexs.add(headerEntity.getIndex());
}
String currentFirstSpell = "";
for (int i = mHeaderSize - headerEntities.length; i < mItems.size(); i++) {
if (mNeedShutdown) return;
String firstSpell = mItems.get(i).getFirstSpell();
if (!currentFirstSpell.equals(firstSpell)) {
mTitleMap.put(i + mTitleMap.size(), firstSpell);
currentFirstSpell = firstSpell;
}
}
}
private boolean processIndexEntity(List<T> items) {
for (T t : items) {
if (mNeedShutdown) return true;
String pinyin = PinyinUtil.getPingYin(t.getName());
boolean isPolyphone = PinyinUtil.matchingPolyphone(pinyin);
if (!isPolyphone) {
t.setFirstSpell(pinyin.substring(0, 1).toUpperCase());
t.setSpell(pinyin);
} else {
t.setFirstSpell(PinyinUtil.getMatchingFirstPinyin(pinyin).toUpperCase());
t.setSpell(PinyinUtil.getMatchingPinyin(pinyin));
t.setName(PinyinUtil.getMatchingHanzi(t.getName()));
}
}
return false;
}
private void processHeaderEntity(IndexHeaderEntity[] headerEntities) {
for (IndexHeaderEntity indexHeaderEntity : headerEntities) {
for (Object o : indexHeaderEntity.getHeaderList()) {
IndexEntity t = (IndexEntity) o;
String pinyin = PinyinUtil.getPingYin(t.getName());
boolean isPolyphone = PinyinUtil.matchingPolyphone(pinyin);
if (!isPolyphone) {
t.setSpell(pinyin);
} else {
t.setSpell(PinyinUtil.getMatchingPinyin(pinyin));
t.setName(PinyinUtil.getMatchingHanzi(t.getName()));
}
}
}
}
public SparseArray<String> getTitleMap() {
return mTitleMap;
}
public int getIndexMapPosition(int position) {
return mTitleMap.keyAt(position);
}
public String getIndex(int position) {
return mTitleMap.get(position);
}
public List<String> getHeaderIndexs() {
return mHeaderIndexs;
}
int getHeaderSize() {
return mHeaderEntitied.length;
}
int getLastestTitlePostion(int position) {
for (int i = position; i >= 0; i--) {
String value = mTitleMap.get(i);
if (value != null) {
return i - mTitleMap.indexOfKey(i);
}
}
return position;
}
public T getRealItem(int position) {
if (mIsFilter && mFilterList.size() > 0) {
return mFilterList.get(position);
}
if (mItems.size() <= 0) return null;
return mItems.get(getItemMappingPostion(position));
}
public int getItemMappingPostion(int position) {
for (int i = position - 1; i >= 0; i--) {
String value = mTitleMap.get(i);
if (value != null) {
return position - 1 - mTitleMap.indexOfKey(i);
}
}
return position;
}
String getItemFirstSpell(int position) {
if (position < mHeaderSize) {
// header区域
for (int i = position; i >= 0; i--) {
if (mTitleMap.indexOfKey(i) > -1) {
String title = mTitleMap.get(i);
for (IndexHeaderEntity item : mHeaderEntitied) {
if (item.getHeaderTitle().equals(title)) {
return item.getIndex();
}
}
}
}
}
return mItems.get(getLastestTitlePostion(position)).getFirstSpell();
}
String getItemTitle(int position) {
if (position < mHeaderSize) {
// header区域
for (int i = position; i >= 0; i--) {
if (mTitleMap.indexOfKey(i) > -1) {
String title = mTitleMap.get(i);
for (IndexHeaderEntity item : mHeaderEntitied) {
if (item.getHeaderTitle().equals(title)) {
return item.getHeaderTitle();
}
}
}
}
}
return mItems.get(getLastestTitlePostion(position)).getFirstSpell();
}
public List<T> getSourceItems() {
return mItems;
}
void setFilterDatas(List<T> filterList) {
mIsFilter = filterList != null;
if (filterList != null) {
if (mFilterList == null) {
mFilterList = new ArrayList<>();
} else {
mFilterList.clear();
}
mFilterList.addAll(filterList);
} else {
mFilterList = null;
}
notifyDataSetChanged();
}
boolean isFilter() {
return mIsFilter;
}
}