该文章主要记录,Rv中的多布局使用。
目录
1. 继承自RecyclerView.Adapter实现聊天多布局
1. 继承自RecyclerView.Adapter实现聊天多布局
实现该类多布局,主要是重写了getItemViewType,然后才是根据不同的数据类型去返回各自相对应的Item子布局。
而在onCreateViewHolder()中才是加载对应的itemType转换为对应的view即可。
/**
* @author crazyZhangxl on 2019/1/15.
* Describe: 多布局实现聊天通信 纯UI
*/
public class SessionAdapter extends RecyclerView.Adapter<OneViewHolder>{
private Context mContext;
private List<Message> mMessagesList;
private static final int SEND_TEXT = R.layout.item_text_send;
private static final int RECEIVE_TEXT = R.layout.item_text_receive;
private static final int UNDEFINE_MSG = R.layout.item_no_support_msg_type;
/**
* 构造函数----
* @param context
* @param messagesList
*/
public SessionAdapter(Context context, List<Message> messagesList) {
mContext = context;
mMessagesList = messagesList;
}
/**
* 创建ViewHolder
* @param viewGroup 父亲组件
* @param viewType 文本布局资源文件[对应getItemViewType返回的类型]
* @return
*/
@NonNull
@Override
public OneViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
return new OneViewHolder(LayoutInflater.from(mContext).inflate(viewType, viewGroup,false), mContext);
}
/**
* 绑定ViewHolder设置初始化
* @param viewHolder
* @param position
*/
@Override
public void onBindViewHolder(@NonNull OneViewHolder viewHolder, int position) {
// 设置时间
setTime(viewHolder,position);
setName(viewHolder,position);
setContent(viewHolder,position);
}
private void setName(OneViewHolder viewHolder, int position) {
TextView tvName = viewHolder.mConvertView.findViewById(R.id.tvName);
tvName.setText(mMessagesList.get(position).getSendName());
}
private void setContent(OneViewHolder viewHolder, int position) {
Message message = mMessagesList.get(position);
if (message instanceof TextMessage){
TextView tvMessage = viewHolder.mConvertView.findViewById(R.id.tvText);
TextMessage textMessage = (TextMessage) mMessagesList.get(position);
tvMessage.setText(textMessage.getTextInfo());
}
}
private void setTime(OneViewHolder viewHolder, int position) {
TextView tvTime = viewHolder.mConvertView.findViewById(R.id.tvTime);
Message message = mMessagesList.get(position);
long sendTime = message.getSendTime();
if (position > 0){
long preTime = mMessagesList.get(position - 1).getSendTime();
if (sendTime - preTime > 5*60*1000){
tvTime.setVisibility(View.VISIBLE);
tvTime.setText(TimeUtils.getInstance().longToTime(sendTime));
}else {
tvTime.setVisibility(View.GONE);
}
}else {
tvTime.setVisibility(View.VISIBLE);
tvTime.setText(TimeUtils.getInstance().longToTime(sendTime));
}
}
/**
* 对应各种消息类型[多布局的核心]
* @param position 对应的下标position
* @return
*/
@Override
public int getItemViewType(int position) {
int viewType = UNDEFINE_MSG;
Message message = mMessagesList.get(position);
boolean isSend = message.getDirection() == MessageDirection.SEND.integerValue;
switch (message.getMessageType()){
case TEXT:
viewType = isSend?SEND_TEXT:RECEIVE_TEXT;
break;
case IMAGE:
break;
default:
break;
}
return viewType;
}
@Override
public int getItemCount() {
if (mMessagesList == null){
return 0;
}
return mMessagesList.size();
}
}
/**
* @author crazyZhangxl on 2019/1/15.
* Describe: 基本的ViewHolder
*/
public class OneViewHolder extends RecyclerView.ViewHolder{
protected View mConvertView;
private Context mContext;
public OneViewHolder(@NonNull View itemView) {
super(itemView);
}
public OneViewHolder(@NonNull View itemView, Context context) {
super(itemView);
mConvertView = itemView;
mContext = context;
}
public View getConvertView() {
return mConvertView;
}
public void setConvertView(View convertView) {
mConvertView = convertView;
}
public Context getContext() {
return mContext;
}
public void setContext(Context context) {
mContext = context;
}
}
拓展内容
可以学习下优秀的人封装的ViewHolder,特点是对View的操作更加简洁了,而且封装了item的各种操作事件处理。还有一个知识点是 SparseArray<Views>的学习以及使用,优化的缓存方案。
public class LQR