/* * Copyright (c) 2020 WildFireChat. All rights reserved. */ package cn.wildfire.chat.kit.contact; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.RecyclerView; import cn.wildfire.chat.kit.R; import cn.wildfire.chat.kit.contact.model.FooterValue; import cn.wildfire.chat.kit.contact.model.HeaderValue; import cn.wildfire.chat.kit.contact.model.UIUserInfo; import cn.wildfire.chat.kit.contact.viewholder.UserViewHolder; import cn.wildfire.chat.kit.contact.viewholder.footer.FooterViewHolder; import cn.wildfire.chat.kit.contact.viewholder.header.HeaderViewHolder; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; public class UserListAdapter extends RecyclerView.Adapter { private static final int TYPE_CONTACT = 1024; private static final int TYPE_FOOTER_START_INDEX = 2048; protected List users; protected List favUsers; protected Fragment fragment; private List headerValues; private List footerValues; protected OnUserClickListener onUserClickListener; protected OnHeaderClickListener onHeaderClickListener; protected OnFooterClickListener onFooterClickListener; public UserListAdapter(Fragment fragment) { super(); this.fragment = fragment; } public List getUsers() { return users; } public List getFavUsers() { return favUsers; } public int getContactCount() { return userCount(); } public void setUsers(List users) { this.users = users; notifyDataSetChanged(); } public void setOneHeaderValue(int position, HeaderValue headerValue) { HeaderValueWrapper headerValueWrapper = headerValues.get(position); headerValueWrapper.headerValue = headerValue; notifyDataSetChanged(); } public void setFavUsers(List favUsers) { this.favUsers = favUsers; notifyDataSetChanged(); } public void setOnUserClickListener(OnUserClickListener onUserClickListener) { this.onUserClickListener = onUserClickListener; } public void setOnHeaderClickListener(OnHeaderClickListener onHeaderClickListener) { this.onHeaderClickListener = onHeaderClickListener; } public void setOnFooterClickListener(OnFooterClickListener onFooterClickListener) { this.onFooterClickListener = onFooterClickListener; } @NonNull @Override final public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { RecyclerView.ViewHolder viewHolder; View itemView; // header if (viewType < TYPE_CONTACT) { HeaderValueWrapper wrapper = headerValues.get(viewType); itemView = LayoutInflater.from(fragment.getActivity()).inflate(wrapper.layoutResId, parent, false); try { Constructor constructor = wrapper.headerViewHolderClazz.getConstructor(Fragment.class, UserListAdapter.class, View.class); viewHolder = (HeaderViewHolder) constructor.newInstance(fragment, this, itemView); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("create header viewHolder failed"); } itemView.setOnClickListener(v -> { if (onHeaderClickListener != null) { onHeaderClickListener.onHeaderClick(viewHolder.getAdapterPosition()); } }); // contact } else if (viewType == TYPE_CONTACT) { viewHolder = onCreateContactViewHolder(parent, viewType); // footer } else { FooterValueWrapper wrapper = footerValues.get(viewType - TYPE_FOOTER_START_INDEX); itemView = LayoutInflater.from(fragment.getActivity()).inflate(wrapper.layoutResId, parent, false); try { Constructor constructor = wrapper.footerViewHolderClazz.getConstructor(Fragment.class, UserListAdapter.class, View.class); viewHolder = (FooterViewHolder) constructor.newInstance(fragment, this, itemView); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("create footer viewHolder failed"); } itemView.setOnClickListener(v -> { if (onFooterClickListener != null) { onFooterClickListener.onFooterClick(viewHolder.getAdapterPosition() - headerCount() - userCount() - favUserCount()); } }); } return viewHolder; } protected RecyclerView.ViewHolder onCreateContactViewHolder(@NonNull ViewGroup parent, int viewType) { View itemView; itemView = LayoutInflater.from(fragment.getActivity()).inflate(R.layout.contact_item_contact, parent, false); UserViewHolder viewHolder = new UserViewHolder(fragment, this, itemView); itemView.setOnClickListener(v -> { if (onUserClickListener != null) { int position = viewHolder.getAdapterPosition(); if(favUserCount() > 0 && position - headerCount() < favUserCount()){ onUserClickListener.onUserClick(favUsers.get(position - headerCount())); }else { onUserClickListener.onUserClick(users.get(position - headerCount() - favUserCount())); } } }); return viewHolder; } private void processOnLongClick(RecyclerView.ViewHolder viewHolder) { // not implement yet } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { if (holder instanceof UserViewHolder) { if(favUserCount() > 0 && position - headerCount() < favUserCount()){ ((UserViewHolder) holder).onBind(favUsers.get(position - headerCount())); }else { ((UserViewHolder) holder).onBind(users.get(position - headerCount() - favUserCount())); } } else if (holder instanceof HeaderViewHolder) { HeaderValueWrapper wrapper = headerValues.get(position); ((HeaderViewHolder) holder).onBind(wrapper.headerValue); } else if (holder instanceof FooterViewHolder) { FooterValueWrapper wrapper = footerValues.get(position - headerCount() - userCount() - favUserCount()); ((FooterViewHolder) holder).onBind(wrapper.footerValue); } holder.itemView.setTag(position); } @Override public int getItemViewType(int position) { if (position < headerCount()) { return position; } else if (position < headerCount() + userCount() + favUserCount()) { return TYPE_CONTACT; } else { return TYPE_FOOTER_START_INDEX + (position - headerCount() - userCount() - favUserCount()); } } @Override public int getItemCount() { return headerCount() + footerCount() + userCount() + favUserCount(); } public void addHeaderViewHolder(Class clazz, int layoutResId, HeaderValue value) { if (headerValues == null) { headerValues = new ArrayList<>(); } int position = headerCount(); headerValues.add(new HeaderValueWrapper(clazz, layoutResId, value)); notifyItemInserted(position); } public void updateHeader(int index, HeaderValue value) { HeaderValueWrapper wrapper = headerValues.get(index); headerValues.set(index, new HeaderValueWrapper(wrapper.headerViewHolderClazz, wrapper.layoutResId, value)); notifyItemChanged(index); } public void addFooterViewHolder(Class clazz, int layoutResId, FooterValue value) { if (footerValues == null) { footerValues = new ArrayList<>(); } int footerCount = footerCount(); footerValues.add(new FooterValueWrapper(clazz, layoutResId, value)); notifyItemInserted(headerCount() + userCount() + favUserCount() + footerCount); } public void updateFooter(int index, FooterValue value) { FooterValueWrapper wrapper = footerValues.get(index); footerValues.set(index, new FooterValueWrapper(wrapper.footerViewHolderClazz, wrapper.layoutResId, value)); notifyItemChanged(headerCount() + userCount() + favUserCount() + index); } public int headerCount() { return headerValues == null ? 0 : headerValues.size(); } private int userCount() { return users == null ? 0 : users.size(); } private int favUserCount() { return favUsers == null ? 0 : favUsers.size(); } public int footerCount() { return footerValues == null ? 0 : footerValues.size(); } public interface OnUserClickListener { void onUserClick(UIUserInfo userInfo); } public interface OnHeaderClickListener { void onHeaderClick(int index); } public interface OnFooterClickListener { void onFooterClick(int index); } static class HeaderValueWrapper { Class headerViewHolderClazz; int layoutResId; HeaderValue headerValue; public HeaderValueWrapper(Class headerViewHolderClazz, int layoutResId, HeaderValue headerValue) { this.headerViewHolderClazz = headerViewHolderClazz; this.layoutResId = layoutResId; this.headerValue = headerValue; } } static class FooterValueWrapper { Class footerViewHolderClazz; int layoutResId; FooterValue footerValue; public FooterValueWrapper(Class footerViewHolderClazz, int layoutResId, FooterValue footerValue) { this.footerViewHolderClazz = footerViewHolderClazz; this.layoutResId = layoutResId; this.footerValue = footerValue; } } }