RecyclerView实现聊天界面

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010221508/article/details/88851255
  • 先看一下效果图
    在这里插入图片描述

  • RecyclerView简介

    RecyclerView是从Android5.0开始,谷歌公司推出的一个用于大量数据展示的新控件。RecyclerView可以替代传统的ListView,它更加强大和灵活,RecyclerView的官方定义如下

     A flexible view for providing a limited window into a large data set
    

    从定义可以看出flexible是其优点,RecyclerView是support-v7包中的新组件。

    RecyclerView相对于ListView的优点如下:

    1.RecyclerView封装了viewHolder的回收复用,也就是说Recyclerview标准化了viewHolder。

    2.设置布局管理器以控制item的布局方式,横向、竖向以及瀑布流方式,可以调用setLayoutManager设置布局方式。RecyclerView的布局管理器有LinearLayoutManager、GridLayoutManager和StaggeredGridLayoutManager。也可以调用布局管理器的setOrientation方法设置recyclerView的滚动方向。

    3.可以设置RecyclerView的间隔样式,通过继承RecyclerView的ItemDecoration这个类,去自定义间隔样式,然后调用addItemDecoration去添加间隔样式。

    4.可以控制item的增删动画,通过ItemAnimator这个类进行控制,调用setItemAnimator方法实现。

  • 实现原理

     public class RecycleViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
         private List<ChatWithFriendBean> mList;
         private Context mContext;
         private LayoutInflater mInflater;
         private AdapterView.OnItemClickListener mListener;
         private RequestOptions options;
     
         public interface OnItemClickListener{
             void onItemClick(ChatWithFriendBean bean);
         }
     
         public RecycleViewAdapter(Context context,List<ChatWithFriendBean> list) {
             mContext = context;
             mList = list;
             mInflater = LayoutInflater.from(mContext);
             options = new RequestOptions().centerCrop();
         }
         
     	 //通过不同的viewType创建不同的viewHolder
         @NonNull
         @Override
         public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
             if (viewType == ITEM_TYPE.TYPE_FRIEND_MSG.ordinal()) {
                 return new FromMsgHolder(mInflater.inflate(R.layout.item_chat_friend,viewGroup,false));
             }else {
                 return new ToMsgHolder(mInflater.inflate(R.layout.item_chat_me,viewGroup,false));
             }
         }
     	
     	 //viewHolder和数据进行绑定
         @Override
         public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
             ChatWithFriendBean chatWithFriendBean = mList.get(i);
             int itemViewType = getItemViewType(i);
             if (itemViewType == ITEM_TYPE.TYPE_FRIEND_MSG.ordinal()) {
                 Glide.with(mContext).load(mContext.getResources().getDrawable(R.drawable.small_cat)).into(((FromMsgHolder)viewHolder).headImage);
                 if (chatWithFriendBean.getMapUrl() != null && !"".equals(chatWithFriendBean.getMapUrl())) {
                     ((FromMsgHolder)viewHolder).llAddressInfo.setVisibility(View.VISIBLE);
                     ((FromMsgHolder)viewHolder).content.setVisibility(View.GONE);
                     ((FromMsgHolder)viewHolder).addressContent.setText(chatWithFriendBean.getPoiname() + "\n" + chatWithFriendBean.getLabel());
                     Glide.with(mContext).load(chatWithFriendBean.getMapUrl()).apply(options).into(((FromMsgHolder)viewHolder).address);
                 }else {
                     ((FromMsgHolder)viewHolder).llAddressInfo.setVisibility(View.GONE);
                     ((FromMsgHolder)viewHolder).content.setVisibility(View.VISIBLE);
                     ((FromMsgHolder)viewHolder).content.setText(chatWithFriendBean.getContent());
                 }
             }else {
                 Glide.with(mContext).load(mContext.getResources().getDrawable(R.drawable.small_dog)).into(((ToMsgHolder)viewHolder).headImage);
                 if (chatWithFriendBean.getMapUrl() != null && !"".equals(chatWithFriendBean.getMapUrl())) {
                     ((ToMsgHolder)viewHolder).llAddressInfo.setVisibility(View.VISIBLE);
                     ((ToMsgHolder)viewHolder).content.setVisibility(View.GONE);
                     Glide.with(mContext).load(chatWithFriendBean.getMapUrl()).apply(options).into(((ToMsgHolder)viewHolder).address);
                     ((ToMsgHolder)viewHolder).addressContent.setText(chatWithFriendBean.getPoiname() + "\n" + chatWithFriendBean.getLabel());
                 }else {
                     ((ToMsgHolder)viewHolder).llAddressInfo.setVisibility(View.GONE);
                     ((ToMsgHolder)viewHolder).content.setVisibility(View.VISIBLE);
                     ((ToMsgHolder)viewHolder).content.setText(chatWithFriendBean.getContent());
                 }
             }
         }
     	
         //定义一个枚举,分别表示接受消息和发送消息
         public enum ITEM_TYPE {
             TYPE_FRIEND_MSG,
             TYPE_ME_MSG
         }
     	
     	 //根据消息的属性返回不同的viewType
         @Override
         public int getItemViewType(int position) {
             if (mList.get(position).isFriendMsg()) {
                 return ITEM_TYPE.TYPE_FRIEND_MSG.ordinal();
             }else {
                 return ITEM_TYPE.TYPE_ME_MSG.ordinal();
             }
         }
     	
     	 //刷新消息接口
         public void update(List<ChatWithFriendBean> list) {
             mList = list;
             notifyDataSetChanged();
         }
     
         @Override
         public long getItemId(int position) {
             return position;
         }
     
         @Override
         public int getItemCount() {
             if (mList == null || mList.size() == 0) return 0;
             return mList.size();
         }
     	
     	 //接收的消息的viewHolder
         public static class FromMsgHolder extends RecyclerView.ViewHolder {
             private ImageView headImage;
             private TextView content;
             private ImageView address;
             private LinearLayout llAddressInfo;
             private TextView addressContent;
     
             public FromMsgHolder(View itemView) {
                 super(itemView);
                 headImage = itemView.findViewById(R.id.friend_avatar);
                 content = itemView.findViewById(R.id.friend_content);
                 address = itemView.findViewById(R.id.friend_address);
                 llAddressInfo = itemView.findViewById(R.id.ll_address_info);
                 addressContent = itemView.findViewById(R.id.address_content);
             }
         }
     	
     	 //发送的消息的viewHolder
         public static class ToMsgHolder extends RecyclerView.ViewHolder {
             private ImageView headImage;
             private TextView content;
             private ImageView address;
             private LinearLayout llAddressInfo;
             private TextView addressContent;
     
             public ToMsgHolder(View itemView) {
                 super(itemView);
                 headImage = itemView.findViewById(R.id.me_avatar);
                 content = itemView.findViewById(R.id.me_content);
                 address = itemView.findViewById(R.id.me_address);
                 llAddressInfo = itemView.findViewById(R.id.ll_address_info);
                 addressContent = itemView.findViewById(R.id.address_content);
             }
         }
     }
    

    上面是Adapter的创建过程,就是通过getItemViewType、onCreateViewHolder和bindViewHolder这几个方法创建不同的viewHolder并且和各自的数据进行绑定的,这样RecyclerView就可以显示不同的Item了。

     //创建RecyclerView对象
     chatRecyclerView = findViewById(R.id.chatRecyclerView);
     //创建adapter对象
     chatAdapter = new RecycleViewAdapter(this,getData());
     //设置布局方式
     chatRecyclerView.setLayoutManager(new LinearLayoutManager(this));
     //recyclerView和adapter绑定
     chatRecyclerView.setAdapter(chatAdapter);
    
     //模拟数据
     private List<ChatWithFriendBean> getData() {
         List<ChatWithFriendBean> mList = new ArrayList<>();
         ChatWithFriendBean friChatBeanOne = new ChatWithFriendBean();
         friChatBeanOne.setContent("你好,小汪");
         friChatBeanOne.setFriendMsg(true);
         mList.add(friChatBeanOne);
         ChatWithFriendBean meChatBeanOne = new ChatWithFriendBean();
         meChatBeanOne.setContent("在的,小喵,干啥");
         meChatBeanOne.setFriendMsg(false);
         mList.add(meChatBeanOne);
         ChatWithFriendBean friChatBeanTwo = new ChatWithFriendBean();
         friChatBeanTwo.setContent("在哪里呢");
         friChatBeanTwo.setFriendMsg(true);
         mList.add(friChatBeanTwo);
         ChatWithFriendBean meChatBeanTwo = new ChatWithFriendBean();
         meChatBeanTwo.setContent("在逛街");
         meChatBeanTwo.setFriendMsg(false);
         mList.add(meChatBeanTwo);
         ChatWithFriendBean friChatBeanThree = new ChatWithFriendBean();
         friChatBeanThree.setContent("在哪里逛街呢,地址给我发一下,去找你");
         friChatBeanThree.setFriendMsg(true);
         mList.add(friChatBeanThree);
         ChatWithFriendBean meChatBeanThree = new ChatWithFriendBean();
         meChatBeanThree.setMapUrl("http://restapi.amap.com/v3/staticmap?markers=mid,0xFF0000,A:116.37359,39.92437&key=352c8f38a730448b4b21d35f355a3bdb");
         meChatBeanThree.setPoiname("广济寺");
         meChatBeanThree.setLabel("北京城内西城区阜成门内大街25号");
         meChatBeanThree.setFriendMsg(false);
         mList.add(meChatBeanThree);
         ChatWithFriendBean friChatBeanFour = new ChatWithFriendBean();
         friChatBeanFour.setMapUrl("http://restapi.amap.com/v3/staticmap?markers=mid,0xFF0000,A:116.38359,39.62437&key=352c8f38a730448b4b21d35f355a3bdb");
         friChatBeanFour.setPoiname("南薰殿");
         friChatBeanFour.setLabel("南薰殿位于外朝西路,武英殿西南");
         friChatBeanFour.setFriendMsg(true);
         mList.add(friChatBeanFour);
         return mList;
     }
    

    RecyclerView实现聊天界面就是这样做的
    最后附上demo代码地址:
    https://github.com/xinhuashi/ChatRecyclerView.git

猜你喜欢

转载自blog.csdn.net/u010221508/article/details/88851255