公司想做一个客服系统,要求聊天内容要对外保密,不允许用第三方SDK,这要求也是略严格了,搜索了一下网上的博客,质量好的Demo大多基于第三方的UI框架,无奈只能硬着头皮自己摸索一下,时间允许的话再慢慢优化吧。
<big>布局</big>
三部分:标题栏,聊天内容,输入框。
标题栏写了一个简单的自定义控件,可以控制标题文字和一个左上角的返回按钮。聊天内容选择下拉刷新布局(PtrFrameLayout)包裹一个RecycleView ,下拉刷新查询历史数据。底部输入框暂时用相对布局堆起来,提供emoji表情和文字输入功能,将来如果有时间将输入框写成自定义控件。
标题是长链接的链接状态,链接成功后显示对方信息,这里不做累述。
RecycleView 适配器里,设置两种类型,发送消息和接受消息
public int getItemViewType(int position) {
//判断消息类型
if (isSend) {
return ITEM_TYPE.ITEM_RIGHT.ordinal();//发送
} else {
return ITEM_TYPE.ITEM_LEFT.ordinal();//接收
}
} ```
模拟发送两条信息看看
![聊天信息测试.png](http://upload-images.jianshu.io/upload_images/3027657-738c4f6a4bc08f0b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
信息的气泡框的 .9图片需要仔细调整,不然很丑。
点击发送按钮,或者收到一条消息,更新页面。
public void add(int pos) {
notifyItemInserted(pos);
notifyDataSetChanged();
}
如果数据很多,再发送和接收消息后,页面需要定位到最后一条信息,控制recycleview滚动,用到recycleview的layoutManager
public void scrollToBottom() {
layoutManager.scrollToPosition(list.size()-1);
}
如果是查询聊天记录,并且聊天记录有多条,我们一般采用的是下拉刷新的办法,刷新成功后,页面不会滚动好刷新后的提一条数据,而是停留在刷新位置,我们向上滑动时,才会展示历史纪录,此时要看想要一次查询多少信息,例如如果查询10条信息,页面更新后,第一条item可见位置应该是第11个item位置
public void scrollToLastPos() {
int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();
//每次更新10条信息,为了刷新后仍固定在相同的页面位置,所以滑动位置为 lastPos + 9 ,9为为了可以展示一个刷新出来的item
layoutManager.scrollToPosition(lastVisibleItemPosition + 9);
}
关于键盘的问题
为了避免布局被软键盘覆盖,我们需要监听键盘弹出,当键盘弹出时,聊天记录定位到记录最后位置。或者设置windowSoftInputMode 也可以,但是这里没有采用这样的方式,你可以自己测试。
判断键盘是否弹出思路:判断窗口可见区域的大小,如果屏幕高度和应用窗口可见区域高度差值大于整个屏幕的1/3,则便是软件盘显示中,否则为键盘隐藏状态。
参考链接:http://blog.csdn.net/ccpat/article/details/46730771
对输入框进行一些限制
android:inputType="textMultiLine"//允许多行显示
android:maxLines="3"//再无内容情况下,最多显示3行
android:maxLength="75"//输入内容不超过75个字符
android:maxEms="10"//每行长都不超过10ems长度,ems长度单位会随着字体大小的变化而变化
[demo](https://github.com/LikeBaker/LikePorject)