聊天中的时间分割线 结合recylerview

2023-10-28 18:20

本文主要是介绍聊天中的时间分割线 结合recylerview,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

效果:



实现的方式有很多种 可以在耽搁item布局中隐藏或者显示 但是耦合度太高 不灵活(网易云信IM demo) 下面介绍用recylerview的分割线来动态画


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.TypedValue;
import android.view.View;/*** Description  聊天界面 时间分割线  间隔5分钟* author  youxuan  E-mail:xuanyouwu@163.com* date createTime:2017/4/29* version 1.0.0*/
public class ChatItemDecoration extends RecyclerView.ItemDecoration {private Paint mPaint;private Rect mBounds;private float mTextSize;private static final int DEFAULE_COLOR_TEXT = 0xFFA6A6A6;private static final int DEFAULE_COLOR_LINE = DEFAULE_COLOR_TEXT;private float lineHeight;//线条高度private float dividerHeight;//整个分割线高度private float sp2px(@NonNull Context context, int sp) {return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, context.getResources().getDisplayMetrics());}private float dp2px(@NonNull Context context, int dp) {return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());}public ChatItemDecoration(@NonNull Context context) {mPaint = new Paint();mPaint.setTextSize(mTextSize = sp2px(context, 16));mPaint.setColor(DEFAULE_COLOR_TEXT);mPaint.setAntiAlias(true);mBounds = new Rect();lineHeight = dp2px(context, 1);dividerHeight = mTextSize * 3;}@Overridepublic void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {//super.onDraw(c, parent, state);final int childCount = parent.getChildCount();for (int i = 0; i < childCount; i++) {final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) parent.getChildAt(i).getLayoutParams();int position = params.getViewLayoutPosition();if (position % 5 != 0) continue;//注意 这里为模拟 找到你adapter中的时间分割点final View child = parent.getChildAt(i);String tag = "上午 10:36";//模拟数据mPaint.setColor(DEFAULE_COLOR_TEXT);mPaint.getTextBounds(tag, 0, tag.length(), mBounds);if (mBounds.width() >= child.getWidth()) {c.drawText(tag, 0, child.getBottom(), mPaint);} else {float txtStartX = (child.getWidth() - mBounds.width()) / 2;float txtEndX = txtStartX + mBounds.width();float dividerCenterY = dividerHeight / 2 + child.getBottom();//画中间文本c.drawText(tag, txtStartX, dividerCenterY + mTextSize * 0.25f, mPaint);float lineWidth = mTextSize * 2;float lineTxtMargin = mTextSize;float leftLineStartX = txtStartX - lineWidth - lineTxtMargin;float leftLineEndX = leftLineStartX + lineWidth;float rightLineStartX = txtEndX + lineTxtMargin;float rightLineEndX = rightLineStartX + lineWidth;//画两边的线条if (leftLineStartX > 0 && rightLineEndX < child.getWidth()) {mPaint.setColor(DEFAULE_COLOR_LINE);c.drawRect(leftLineStartX, dividerCenterY - lineHeight * 0.5f, leftLineEndX, dividerCenterY + lineHeight * 0.5f, mPaint);mPaint.setColor(DEFAULE_COLOR_LINE);c.drawRect(rightLineStartX, dividerCenterY - lineHeight * 0.5f, rightLineEndX, dividerCenterY + lineHeight * 0.5f, mPaint);}}}}@Overridepublic void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {super.getItemOffsets(outRect, view, parent, state);outRect.set(0, 0, 0, (int) dividerHeight);}
}


用法:

 recyclerView.addItemDecoration(new ChatItemDecoration(getContext()));





进一步完善 对于消息 adapter 最适合做管理者 他明确知道对应位置对应的消息对象 进而能控制时间是否显示,所有我声明了一个接口

import android.support.annotation.NonNull;/*** Description  {@link ChatItemDecoration}* author  youxuan  E-mail:xuanyouwu@163.com* date createTime:2017/4/29* version 1.0.0*/
public interface ITimeDividerInterface {/*** 是否展示时间分割线** @param pos* @return*/boolean isShowTimeDivider(int pos);/*** 展示的时间** @param pos* @return*/@NonNullString getShowTime(int pos);}

让你的adpter实现这个接口,直接用:

linearLayoutManager = new LinearLayoutManager(getContext());recyclerView.setLayoutManager(linearLayoutManager);recyclerView.setHasFixedSize(true);recyclerView.setAdapter(chatAdapter = new ChatAdapter(getLoadedLoginToken()));recyclerView.addItemDecoration(new ChatItemDecoration(getContext(), chatAdapter));


adapter 代码如下:


import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;import static com.netease.nimlib.sdk.msg.constant.MsgDirectionEnum.In;
import static com.netease.nimlib.sdk.msg.constant.MsgDirectionEnum.Out;/*** Description* author  youxuan  E-mail:xuanyouwu@163.com* date createTime:2017/4/24* version 1.0.0*/
public class ChatAdapter extends BaseArrayRecyclerAdapter<IMCustomerMessageEntity> implements ITimeDividerInterface {private Set<Long> timeShowArray = new HashSet<>();//时间分割线消息private Comparator<Long> longComparator = new Comparator<Long>() {@Overridepublic int compare(Long o1, Long o2) {if (o1 != null && o2 != null) {return o1.compareTo(o2);}return 0;}};private final int TIME_DIVIDER = 5 * 60 * 1_000;/*** 处理时间分割线** @param imMessage* @param position*/private void addTimeDividerArray(IMCustomerMessageEntity imMessage, int position) {if (imMessage == null) return;if (imMessage.imMessage == null) return;//消息时间本身已经有序//用云信的时间if (timeShowArray.isEmpty()) {timeShowArray.add(imMessage.imMessage.getTime());} else {if (!timeShowArray.contains(imMessage.imMessage.getTime())) {if (imMessage.imMessage.getTime() - Collections.max(timeShowArray, longComparator).longValue() >= TIME_DIVIDER) {timeShowArray.add(imMessage.imMessage.getTime());} else if (Collections.min(timeShowArray, longComparator).longValue() - imMessage.imMessage.getTime() >= TIME_DIVIDER) {timeShowArray.add(imMessage.imMessage.getTime());}}}}/*** 是否显示时间 时间间隔5分钟** @param pos* @return*/@Overridepublic boolean isShowTimeDivider(int pos) {IMCustomerMessageEntity item = getItem(pos);return item != null && item.imMessage != null && timeShowArray.contains(item.imMessage.getTime());}/*** 显示的时间字符串 isShowTimeDivider=true 不可以返回null** @param pos* @return*/@NonNull@Overridepublic String getShowTime(int pos) {IMCustomerMessageEntity item = getItem(pos);return item != null && item.imMessage != null ?DateUtils.getTimeShowString(item.imMessage.getTime(), true) : "null";}
}



这篇关于聊天中的时间分割线 结合recylerview的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/295082

相关文章

Feign Client超时时间设置不生效的解决方法

《FeignClient超时时间设置不生效的解决方法》这篇文章主要为大家详细介绍了FeignClient超时时间设置不生效的原因与解决方法,具有一定的的参考价值,希望对大家有一定的帮助... 在使用Feign Client时,可以通过两种方式来设置超时时间:1.针对整个Feign Client设置超时时间

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

Python如何获取域名的SSL证书信息和到期时间

《Python如何获取域名的SSL证书信息和到期时间》在当今互联网时代,SSL证书的重要性不言而喻,它不仅为用户提供了安全的连接,还能提高网站的搜索引擎排名,那我们怎么才能通过Python获取域名的S... 目录了解SSL证书的基本概念使用python库来抓取SSL证书信息安装必要的库编写获取SSL证书信息

Python结合Flask框架构建一个简易的远程控制系统

《Python结合Flask框架构建一个简易的远程控制系统》这篇文章主要为大家详细介绍了如何使用Python与Flask框架构建一个简易的远程控制系统,能够远程执行操作命令(如关机、重启、锁屏等),还... 目录1.概述2.功能使用系统命令执行实时屏幕监控3. BUG修复过程1. Authorization

MySQL 日期时间格式化函数 DATE_FORMAT() 的使用示例详解

《MySQL日期时间格式化函数DATE_FORMAT()的使用示例详解》`DATE_FORMAT()`是MySQL中用于格式化日期时间的函数,本文详细介绍了其语法、格式化字符串的含义以及常见日期... 目录一、DATE_FORMAT()语法二、格式化字符串详解三、常见日期时间格式组合四、业务场景五、总结一、

如何利用Java获取当天的开始和结束时间

《如何利用Java获取当天的开始和结束时间》:本文主要介绍如何使用Java8的LocalDate和LocalDateTime类获取指定日期的开始和结束时间,展示了如何通过这些类进行日期和时间的处... 目录前言1. Java日期时间API概述2. 获取当天的开始和结束时间代码解析运行结果3. 总结前言在J

修改若依框架Token的过期时间问题

《修改若依框架Token的过期时间问题》本文介绍了如何修改若依框架中Token的过期时间,通过修改`application.yml`文件中的配置来实现,默认单位为分钟,希望此经验对大家有所帮助,也欢迎... 目录修改若依框架Token的过期时间修改Token的过期时间关闭Token的过期时js间总结修改若依

Go Mongox轻松实现MongoDB的时间字段自动填充

《GoMongox轻松实现MongoDB的时间字段自动填充》这篇文章主要为大家详细介绍了Go语言如何使用mongox库,在插入和更新数据时自动填充时间字段,从而提升开发效率并减少重复代码,需要的可以... 目录前言时间字段填充规则Mongox 的安装使用 Mongox 进行插入操作使用 Mongox 进行更