Как стать автором
Обновить
2
0
Виктор Земцов @ZemtsovVU

Android Team Lead

Отправить сообщение
Я попробовал развить идею и вот что вышло:
Класс CleanAdapter
public class CleanAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
	private final AdapterTypesMap typesMap = new AdapterTypesMap();

	private List itemList; // TODO

	public CleanAdapter() {
		// Здесь компилятор следит чтоб ViewHolder соответствовал классу данных. Т.е. передача AdVo.class, ProgressViewHolder.class вызовет ошибку компиляции
		typesMap.putItem(R.layout.cell_progress, R.layout.cell_progress, ProgressVo.class, ProgressViewHolder.class);
		typesMap.putItem(R.layout.cell_ad, R.layout.cell_ad, AdVo.class, AdViewHolder.class);
		typesMap.putItem(R.layout.cell_user, R.layout.cell_user, UserVo.class, UserViewHolder.class);
	}

	@Override
	public int getItemCount() {
		return itemList.size();
	}

	@Override
	public int getItemViewType(int position) {
		return typesMap.getItemViewType(itemList.get(position));
	}

	@Override
	public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
		return typesMap.createViewHolder(parent, viewType);
	}

	@Override
	public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
		typesMap.bindViewHolder(holder, itemList.get(position));
	}
}



Класс AdapterTypesMap
public class AdapterTypesMap {
	private final Map<Integer /* view type */, AdapterItemType> viewTypesMap = new HashMap<>();
	private final Map<Class /* adapter list item class */, AdapterItemType> listItemTypesMap = new HashMap<>();

	public <T, V extends ViewHolderBase<T>> void putItem(int viewType, int resourceId, Class<T> dataItemClass, Class<V> viewHolderClass) {
		AdapterItemType adapterItemType = new AdapterItemType(viewType, resourceId, viewHolderClass);
		listItemTypesMap.put(dataItemClass, adapterItemType);
		viewTypesMap.put(viewType, adapterItemType);
	}

	public int getItemViewType(Object obj) {
		return listItemTypesMap.get(obj).getViewType();
	}

	public RecyclerView.ViewHolder createViewHolder(ViewGroup parent, int viewType) {
		return viewTypesMap.get(viewType).createViewHolder(parent);
	}

	public void bindViewHolder(RecyclerView.ViewHolder holder, Object obj) {
		listItemTypesMap.get(obj).bind(holder, obj);
	}
}



Интерфейс IAdapterItemType
public interface IAdapterItemType {
	int getViewType();
	RecyclerView.ViewHolder createViewHolder(ViewGroup parent);
	void bind(RecyclerView.ViewHolder holder, Object item);
}



Реализация AdapterItemType
public class AdapterItemType<T extends ViewHolderBase> implements IAdapterItemType {
	private final Class<T> viewHolderClass;
	private final int viewType;
	private final int resourceId;

	public AdapterItemType(int viewType, int resourceId, Class<T> viewHolderClass) {
		this.viewHolderClass = viewHolderClass;
		this.viewType = viewType;
		this.resourceId = resourceId;
	}

	@Override
	public int getViewType() {
		return viewType;
	}

	@Override
	public ViewHolderBase createViewHolder(ViewGroup parent) {
		try {
			View view = LayoutInflater.from(parent.getContext()).inflate(resourceId, parent, false);
			// здесь не обойтись без рефлексии
			return viewHolderClass.getConstructor(View.class).newInstance(view);
		}
		catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public void bind(RecyclerView.ViewHolder holder, Object item) {
		ViewHolderBase holder2 = (ViewHolderBase) holder;
		holder2.bind(item);
	}
}



Базовый клас ViewHolderBase
public abstract class ViewHolderBase<T> extends RecyclerView.ViewHolder {
	public ViewHolderBase(View itemView) {
		super(itemView);
	}

	public abstract void bind(T item);
}



И по одному наследнику классу ViewHolderBase для соответствующих классов данных. Типа такого:
public class UserViewHolder extends ViewHolderBase<UserVo> {
	public UserViewHolder(View itemView) {
		super(itemView);
	}

	@Override
	public void bind(UserVo item) {
		// TODO
	}
}


Информация

В рейтинге
Не участвует
Откуда
Новосибирск, Новосибирская обл., Россия
Дата рождения
Зарегистрирован
Активность