wangxiang 1 year ago
parent
commit
b844c688fd
  1. 58
      app/src/main/java/com/kanglai/push/ui/activity/InstantActivity.java
  2. 19
      app/src/main/java/com/kanglai/push/ui/adapter/ChatRoomListRecyclerAdapter.java
  3. 123
      app/src/main/java/com/kanglai/push/ui/adapter/SoloChatRoomAdapter.java
  4. 172
      app/src/main/java/com/kanglai/push/ui/vm/InstantViewModel.java
  5. BIN
      app/src/main/res/drawable-xxhdpi/skin_messages_right_bubble_highlighted.9.png
  6. 0
      app/src/main/res/drawable-xxhdpi/skin_messages_right_bubble_wechat.9.png
  7. 6
      app/src/main/res/drawable/skin_messages_right_bubble.xml
  8. 71
      app/src/main/res/layout/activity_instant.xml
  9. 165
      app/src/main/res/layout/item_chat_room.xml

58
app/src/main/java/com/kanglai/push/ui/activity/InstantActivity.java

@ -66,30 +66,33 @@ public class InstantActivity extends BaseActivity<ActivityInstantBinding, Instan
return BR.viewModel; return BR.viewModel;
} }
@Override
protected void onStart() {
super.onStart();
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
super.mViewModel.mActivity = this; super.mViewModel.mActivity = this;
// 其他基础控件 mAdapter = new SoloChatRoomAdapter();
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
mRecyclerView = findViewById(R.id.instant_recycler);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
refreshLayout = findViewById(R.id.instant_smart_refresh);
refreshLayout.setEnableScrollContentWhenLoaded(true);
refreshLayout.setOnLoadMoreListener(mViewModel::loadMore);
refreshLayout.setDisableContentWhenRefresh(true);
input_box = findViewById(R.id.instant_input_box); input_box = findViewById(R.id.instant_input_box);
input_box.setFilters(new InputFilter[]{ViewFilterUtil.getNoSpecialCharactersFilter()}); // 去空格、换行符等特殊符号 input_box.setFilters(new InputFilter[]{ViewFilterUtil.getNoSpecialCharactersFilter()});
more_line = findViewById(R.id.iv_more_line); more_line = findViewById(R.id.iv_more_line);
more_fill = findViewById(R.id.iv_more_fill); more_fill = findViewById(R.id.iv_more_fill);
more_line.setOnClickListener(view -> changBottomType()); more_line.setOnClickListener(view -> changBottomType());
more_fill.setOnClickListener(view -> changBottomType()); more_fill.setOnClickListener(view -> changBottomType());
bottom_grid = findViewById(R.id.instant_grid); bottom_grid = findViewById(R.id.instant_grid);
layout_footer = findViewById(R.id.layout_footer); layout_footer = findViewById(R.id.layout_footer);
localPushChatMsg = getIntent().getParcelableExtra(CommonConstant.INSTANT_LAUNCHER_RESULT_KEY); mViewModel.adverseData = getIntent().getParcelableExtra(CommonConstant.INSTANT_LAUNCHER_RESULT_KEY);
if (localPushChatMsg != null) { mViewModel.setTitleText(localPushChatMsg.getUserName());
mViewModel.adverseData = localPushChatMsg; if ("2".equals(localPushChatMsg.getUserType()) || "5".equals(localPushChatMsg.getUserType()) || "0".equals(localPushChatMsg.getUserType())){
mViewModel.init(); layout_footer.setVisibility(View.INVISIBLE);
judgeViewType(localPushChatMsg);
} }
mViewModel.initData(refreshLayout);
mSubscription = RxBus.getInstance().toObservable(com.dolphin.umeng.entity.PushChatMessage.class) mSubscription = RxBus.getInstance().toObservable(com.dolphin.umeng.entity.PushChatMessage.class)
.compose(RxUtil.schedulersTransformer()) .compose(RxUtil.schedulersTransformer())
.compose(RxUtil.exceptionTransformer()) .compose(RxUtil.exceptionTransformer())
@ -110,25 +113,6 @@ public class InstantActivity extends BaseActivity<ActivityInstantBinding, Instan
} }
public void adapterInit(ArrayList<PushChatMessage> requestList) {
final SoloChatRoomAdapter soloChatRoomAdapter = new SoloChatRoomAdapter(requestList, localPushChatMsg);
mAdapter = soloChatRoomAdapter;
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this); // 初始化垂直适配器
mRecyclerView = findViewById(R.id.instant_recycler);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
refreshLayout = findViewById(R.id.instant_smart_refresh);
refreshLayout.setEnableRefresh(true);
refreshLayout.setEnableLoadMore(false);
refreshLayout.setEnableAutoLoadMore(true);
refreshLayout.setEnableScrollContentWhenLoaded(true);
refreshLayout.setOnRefreshListener(v -> mViewModel.loadMore());
refreshLayout.setDisableContentWhenRefresh(true);
mRecyclerView.scrollToPosition(mAdapter.getItemCount() - 1);
}
public void setActivitieResult() { public void setActivitieResult() {
if (!mAdapter.mItemList.isEmpty()) { if (!mAdapter.mItemList.isEmpty()) {
setResult(RESULT_OK, new Intent().putExtra(CommonConstant.INSTANT_LAUNCHER_RESULT_KEY, new LocalPushChatMsg() setResult(RESULT_OK, new Intent().putExtra(CommonConstant.INSTANT_LAUNCHER_RESULT_KEY, new LocalPushChatMsg()
@ -142,17 +126,6 @@ public class InstantActivity extends BaseActivity<ActivityInstantBinding, Instan
} }
} }
/**
* 加载不同用户类型时的界面
* app端不能给 系统/企业用户/企业内部/系统 用户发消息
*/
private void judgeViewType(LocalPushChatMsg data) {
mViewModel.setTitleText(data.getUserName()); // 标题
if ("2".equals(data.getUserType()) || "5".equals(data.getUserType()) || "0".equals(data.getUserType())){
layout_footer.setVisibility(View.INVISIBLE);
}
}
/** 底部功能模块显示开关 */ /** 底部功能模块显示开关 */
private void changBottomType(){ private void changBottomType(){
isShowBottom = !isShowBottom; isShowBottom = !isShowBottom;
@ -180,6 +153,5 @@ public class InstantActivity extends BaseActivity<ActivityInstantBinding, Instan
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
RxSubscriptions.remove(mSubscription); RxSubscriptions.remove(mSubscription);
if (mAdapter != null) mAdapter.clear();
} }
} }

19
app/src/main/java/com/kanglai/push/ui/adapter/ChatRoomListRecyclerAdapter.java

@ -4,13 +4,12 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.blankj.utilcode.util.LogUtils;
import com.kanglai.push.R; import com.kanglai.push.R;
/** /**
@ -58,11 +57,16 @@ public class ChatRoomListRecyclerAdapter extends RecyclerView.Adapter<ChatRoomLi
protected static class ViewHolder extends RecyclerView.ViewHolder{ protected static class ViewHolder extends RecyclerView.ViewHolder{
// 每个item包含的控件 // 每个item包含的控件
public LinearLayout left_layout; // 左侧消息盒子(对方) public RelativeLayout left_layout; // 左侧消息盒子(对方)
public ImageView left_avatar; // 左头像 public ImageView left_avatar; // 左头像
public TextView left_text; // 左文字 public TextView left_text; // 左文字
public LinearLayout right_layout; // 右侧~(我方) public RelativeLayout right_layout; // 右侧~(我方)
public ImageView right_avatar; public ImageView right_avatar;
public ImageView chatting_left_img;
public ImageView chatting_right_img;
public TextView right_text; public TextView right_text;
public TextView send_time; // 发送时间 public TextView send_time; // 发送时间
public TextView system_msg; // 系统消息 public TextView system_msg; // 系统消息
@ -74,9 +78,12 @@ public class ChatRoomListRecyclerAdapter extends RecyclerView.Adapter<ChatRoomLi
left_text = v.findViewById(R.id.chatting_left_text); left_text = v.findViewById(R.id.chatting_left_text);
right_layout = v.findViewById(R.id.layout_chatting_right); right_layout = v.findViewById(R.id.layout_chatting_right);
right_avatar = v.findViewById(R.id.iv_avatar_right); right_avatar = v.findViewById(R.id.iv_avatar_right);
right_text = v.findViewById(R.id.chatting_rigth_text); right_text = v.findViewById(R.id.chatting_right_text);
send_time = v.findViewById(R.id.tv_send_time); send_time = v.findViewById(R.id.tv_send_time);
system_msg = v.findViewById(R.id.tv_system_msg);
chatting_left_img = v.findViewById(R.id.chatting_left_img);
chatting_right_img = v.findViewById(R.id.chatting_right_img);
} }
} }

123
app/src/main/java/com/kanglai/push/ui/adapter/SoloChatRoomAdapter.java

@ -1,53 +1,36 @@
package com.kanglai.push.ui.adapter; package com.kanglai.push.ui.adapter;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.blankj.utilcode.util.CacheDiskUtils; import com.blankj.utilcode.util.CacheDiskUtils;
import com.blankj.utilcode.util.LogUtils; import com.blankj.utilcode.util.StringUtils;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.kanglai.push.R; import com.kanglai.push.R;
import com.kanglai.push.constant.CacheConstant; import com.kanglai.push.constant.CacheConstant;
import com.kanglai.push.entity.LocalPushChatMsg;
import com.kanglai.push.entity.PushChatMessage; import com.kanglai.push.entity.PushChatMessage;
import com.kanglai.push.entity.User; import com.kanglai.push.entity.User;
import com.kanglai.push.util.CustomDeserializer;
import com.kanglai.push.util.TimeFormatUtil;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Date;
import java.util.Locale;
/**
* 单人聊天室适配器
* @Author: liusixiang007
* @since: 2023/6/9
*/
public class SoloChatRoomAdapter extends ChatRoomListRecyclerAdapter{ public class SoloChatRoomAdapter extends ChatRoomListRecyclerAdapter{
public ArrayList<PushChatMessage> mItemList; public ArrayList<PushChatMessage> mItemList = new ArrayList<>();
public User userData = CacheDiskUtils.getInstance().getParcelable(CacheConstant.USER_INFO, com.kanglai.push.entity.User.CREATOR, new User()); // 当前登录用户的数据 public User user = CacheDiskUtils.getInstance().getParcelable(CacheConstant.USER_INFO, com.kanglai.push.entity.User.CREATOR, new User()); // 当前登录用户的数据
public LocalPushChatMsg adverseData; // 聊天方数据 public SoloChatRoomAdapter() {
}
public String alias; // 对方id
public String userId; // 我方id
// private EventListener mEventListener; 单列点击事件
public SoloChatRoomAdapter(ArrayList<PushChatMessage> mItemList, LocalPushChatMsg adverseData) { public SoloChatRoomAdapter(ArrayList<PushChatMessage> mItemList) {
this.mItemList = mItemList; this.mItemList = mItemList;
this.adverseData = adverseData;
this.alias = adverseData.getId();
this.userId = userData.getId();
} }
@Override @Override
@ -57,38 +40,55 @@ public class SoloChatRoomAdapter extends ChatRoomListRecyclerAdapter{
@Override @Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) { public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
super.onBindViewHolder(holder, position);
final PushChatMessage item = mItemList.get(position); final PushChatMessage item = mItemList.get(position);
if (TextUtils.isEmpty(item.getUserId())) return; // 接收id为空时 再不展示数据 onItemBindingTime(holder, item, position);
if (alias.equals(item.getUserId())){ if (StringUtils.equals(user.getId(), item.getUserId())) {
onItemBindingMine(holder, item);
} else {
onItemBindingOther(holder, item); onItemBindingOther(holder, item);
return;
} }
if (userId.equals(item.getUserId())){ }
onItemBindingMine(holder, item);
return; SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
private void onItemBindingTime(ViewHolder holder, PushChatMessage model, int index) {
PushChatMessage prev;
Date lastTime = null;
Date currentTime = null;
if (index > 0) {
prev = mItemList.get(index - 1);
if (prev.getCreateTime() != null) {
try {
lastTime = dateFormat.parse(prev.getCreateTime());
currentTime = dateFormat.parse(model.getCreateTime());
} catch (ParseException ignored) {}
}
}
if ((lastTime != null && currentTime!=null) && (currentTime.getTime() - lastTime.getTime() < 5 * 60 * 1000)) {
holder.send_time.setVisibility(View.GONE);
} else {
holder.send_time.setVisibility(View.VISIBLE);
holder.send_time.setText(model.getCreateTime());
} }
} }
/*展示其他人的消息*/
private void onItemBindingOther(ViewHolder holder, PushChatMessage item) { private void onItemBindingOther(ViewHolder holder, PushChatMessage item) {
holder.system_msg.setVisibility(View.GONE);
holder.send_time.setText(TimeFormatUtil.formatTimeUI(item.getCreateTime()));
holder.right_layout.setVisibility(View.GONE); holder.right_layout.setVisibility(View.GONE);
holder.left_layout.setVisibility(View.VISIBLE);
//后端需要设置头像值
//loadAvatar(holder.right_avatar, user.getAvatar());
holder.chatting_left_img.setVisibility(View.VISIBLE);
holder.left_text.setText(item.getText()); holder.left_text.setText(item.getText());
loadAvatar(holder.left_avatar, adverseData.getAvatar());
} }
/*展示自己的消息*/
private void onItemBindingMine(ViewHolder holder, PushChatMessage item) { private void onItemBindingMine(ViewHolder holder, PushChatMessage item) {
holder.system_msg.setVisibility(View.GONE);
holder.send_time.setText(TimeFormatUtil.formatTimeUI(item.getCreateTime()));
holder.left_layout.setVisibility(View.GONE); holder.left_layout.setVisibility(View.GONE);
holder.right_layout.setVisibility(View.VISIBLE);
loadAvatar(holder.right_avatar, user.getAvatar());
holder.chatting_right_img.setVisibility(View.VISIBLE);
holder.right_text.setText(item.getText()); holder.right_text.setText(item.getText());
loadAvatar(holder.right_avatar, userData.getAvatar());
} }
/*加载头像*/
private void loadAvatar(ImageView avatar, String url) { private void loadAvatar(ImageView avatar, String url) {
Glide.with(avatar.getContext()) Glide.with(avatar.getContext())
.load(url) .load(url)
@ -100,12 +100,8 @@ public class SoloChatRoomAdapter extends ChatRoomListRecyclerAdapter{
.into(avatar); .into(avatar);
} }
/**
* 刷新数据 public SoloChatRoomAdapter refresh(Collection<PushChatMessage> collection) {
* @param collection
* @return
*/
public SoloChatRoomAdapter refresh(Collection<PushChatMessage> collection){
mItemList.clear(); mItemList.clear();
mItemList.addAll(collection); mItemList.addAll(collection);
notifyDataSetChanged(); notifyDataSetChanged();
@ -113,35 +109,18 @@ public class SoloChatRoomAdapter extends ChatRoomListRecyclerAdapter{
return this; return this;
} }
/** public SoloChatRoomAdapter loadMore(Collection<PushChatMessage> collection) {
* 加载历史记录 mItemList.addAll(collection);
* @param collection notifyDataSetChanged();
* @return
*/
public SoloChatRoomAdapter loadHistory(Collection<PushChatMessage> collection){
// mItemList.addAll(0, collection);
notifyItemRangeInserted(0, collection.size());
return this;
}
/**
* 加载是数组最后的一条数据
* @param
* @return
*/
public SoloChatRoomAdapter refreshLastDate(){
notifyItemRangeInserted(mItemList.size() - 1, 1);
return this; return this;
} }
/** 销毁数据 */ public SoloChatRoomAdapter insert(Collection<PushChatMessage> collection) {
public SoloChatRoomAdapter clear(){ mItemList.addAll(0, collection);
mItemList.clear(); notifyItemRangeInserted(0, collection.size());
notifyDataSetChanged();
return this; return this;
} }
public SoloChatRoomAdapter append(PushChatMessage pushChatMessage){ public SoloChatRoomAdapter append(PushChatMessage pushChatMessage){
mItemList.add(pushChatMessage); mItemList.add(pushChatMessage);
notifyItemRangeInserted(mItemList.size() - 1, 1); notifyItemRangeInserted(mItemList.size() - 1, 1);

172
app/src/main/java/com/kanglai/push/ui/vm/InstantViewModel.java

@ -1,12 +1,8 @@
package com.kanglai.push.ui.vm; package com.kanglai.push.ui.vm;
import android.app.Activity;
import android.app.Application; import android.app.Application;
import android.content.Intent;
import android.icu.text.SimpleDateFormat; import android.icu.text.SimpleDateFormat;
import android.icu.util.Calendar; import android.icu.util.Calendar;
import android.os.Handler;
import android.os.Looper;
import android.util.Pair; import android.util.Pair;
import android.view.View; import android.view.View;
@ -26,7 +22,6 @@ import com.dolphin.core.util.RxUtil;
import com.dolphin.core.util.ToastUtil; import com.dolphin.core.util.ToastUtil;
import com.kanglai.push.app.AppApplication; import com.kanglai.push.app.AppApplication;
import com.kanglai.push.constant.CacheConstant; import com.kanglai.push.constant.CacheConstant;
import com.kanglai.push.constant.CommonConstant;
import com.kanglai.push.di.component.DaggerServiceComponent; import com.kanglai.push.di.component.DaggerServiceComponent;
import com.kanglai.push.entity.LocalPushChatMsg; import com.kanglai.push.entity.LocalPushChatMsg;
import com.kanglai.push.entity.MsgVo; import com.kanglai.push.entity.MsgVo;
@ -35,7 +30,7 @@ import com.kanglai.push.entity.User;
import com.kanglai.push.service.PushService; import com.kanglai.push.service.PushService;
import com.kanglai.push.ui.activity.InstantActivity; import com.kanglai.push.ui.activity.InstantActivity;
import com.kanglai.push.util.LocalPushChatMsgUtil; import com.kanglai.push.util.LocalPushChatMsgUtil;
import com.luck.picture.lib.config.PictureConfig; import com.scwang.smart.refresh.layout.api.RefreshLayout;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -59,17 +54,10 @@ public class InstantViewModel extends ToolbarViewModel<InstantActivity>{
public User user = CacheDiskUtils.getInstance().getParcelable(CacheConstant.USER_INFO, User.CREATOR, new User()); public User user = CacheDiskUtils.getInstance().getParcelable(CacheConstant.USER_INFO, User.CREATOR, new User());
public LocalPushChatMsg adverseData; // 对方用户基础信息 public LocalPushChatMsg adverseData; // 对方用户基础信息
public int size = 10;
public int current = 1;
public String cursor = ""; public String cursor = "";
public ArrayList<LocalPushChatMsg> localPushChatMsgs; // 本地缓存的列表数据 public ArrayList<LocalPushChatMsg> localPushChatMsgs; // 本地缓存的列表数据
/** 所有的记录数据 */
private ArrayList<PushChatMessage> requestList = new ArrayList<>();
public InstantViewModel(@NonNull Application application) { public InstantViewModel(@NonNull Application application) {
super(application); super(application);
DaggerServiceComponent DaggerServiceComponent
@ -159,101 +147,81 @@ public class InstantViewModel extends ToolbarViewModel<InstantActivity>{
}); });
}); });
public void init() { public void initData(RefreshLayout refresh) {
pushService.listFriendHistoryMessage( pushService.listFriendHistoryMessage(
MapUtils.newHashMap( MapUtils.newHashMap(
Pair.create("size", size), Pair.create("size", pageSize),
Pair.create("current", current), Pair.create("alias", adverseData.getId()),
Pair.create("alias", adverseData.getId()), Pair.create("userId", user.getId())
Pair.create("userId", user.getId()) ))
)) .compose(RxUtil.schedulersTransformer())
.compose(RxUtil.schedulersTransformer()) .compose(RxUtil.exceptionTransformer())
.compose(RxUtil.exceptionTransformer()) .doOnSubscribe(this)
.doOnSubscribe(this) .subscribe(new DisposableObserver<ResultResponse<Map<String, Object>>>() {
.subscribe(new DisposableObserver<ResultResponse<Map<String, Object>>>() { @Override
@Override public void onNext(ResultResponse<Map<String, Object>> R) {
public void onNext(ResultResponse<Map<String, Object>> R) { if (R.getCode() == R.SUCCESS) {
if (R.getCode() == R.SUCCESS ) { MsgVo msgVo = (MsgVo) R.getData();
MsgVo msgVo = (MsgVo) R.getData(); cursor = msgVo.getCursor();
cursor = msgVo.getCursor(); List<PushChatMessage> data = msgVo.getData();
List<PushChatMessage> data = msgVo.getData(); if (!CollectionUtils.isEmpty(data)) {
if (CollectionUtils.isEmpty(data)) { // 暂无 Collections.reverse(data);
return; mActivity.mAdapter.refresh(data);
} }
Collections.reverse(data); // 把顺序颠倒下方便排列 } else {
requestList.addAll(data); refresh.finishRefresh(false);
ToastUtil.showBottomWarn(R.getMsg());
}else ToastUtil.showBottomWarn(R.getMsg());
}
@Override
public void onError(Throwable e) {
ExceptionHandle.baseExceptionMsg(e);
}
@Override
public void onComplete() {
if (requestList.size() > 0) mActivity.adapterInit(requestList); // 有新数据才做界面刷新
} }
}); }
@Override
public void onError(Throwable e) {
refresh.finishRefresh(false);
ExceptionHandle.baseExceptionMsg(e);
}
@Override
public void onComplete() {}
});
} }
public void loadMore() { // 加载更多数据 public void loadMore(RefreshLayout layout) {
if (CollectionUtils.isEmpty(requestList)) { // 如果此时的列表为空 则重新初始化
init();
return;
}
pushService.listFriendHistoryMessage( pushService.listFriendHistoryMessage(
MapUtils.newHashMap( MapUtils.newHashMap(
Pair.create("size", size), Pair.create("size", pageSize),
Pair.create("current", current + 1), Pair.create("current", pageCurrent += 1),
Pair.create("alias", adverseData.getId()), Pair.create("alias", adverseData.getId()),
Pair.create("userId", user.getId()) Pair.create("userId", user.getId())
)) ))
.compose(RxUtil.schedulersTransformer()) .compose(RxUtil.schedulersTransformer())
.compose(RxUtil.exceptionTransformer()) .compose(RxUtil.exceptionTransformer())
.doOnSubscribe(this) .doOnSubscribe(this)
.subscribe(new DisposableObserver<ResultResponse<Map<String, Object>>>() { .subscribe(new DisposableObserver<ResultResponse<Map<String, Object>>>() {
@Override @Override
public void onNext(ResultResponse<Map<String, Object>> R) { public void onNext(ResultResponse<Map<String, Object>> R) {
if (R.getCode() == R.SUCCESS) { if (R.getCode() == R.SUCCESS) {
MsgVo msgVo = (MsgVo) R.getData(); MsgVo msgVo = (MsgVo) R.getData();
cursor = msgVo.getCursor(); cursor = msgVo.getCursor();
List<PushChatMessage> data = msgVo.getData(); List<PushChatMessage> pushChatMessages = msgVo.getData();
if (CollectionUtils.isEmpty(pushChatMessages)) {
if (CollectionUtils.isEmpty(data)) { ToastUtil.showBottomSuccess("数据加载完毕");
ToastUtil.showBottomSuccess("已加载全部数据"); mActivity.refreshLayout.setEnableRefresh(false);
mActivity.refreshLayout.setEnableRefresh(false); return;
return; }
} Collections.reverse(pushChatMessages);
Collections.reverse(data); mActivity.mAdapter.loadMore(msgVo.getData());
if (data.get(0).getId().equals(requestList.get(0).getId())){ if (mActivity.mAdapter.getItemCount() < R.getTotal()) {
ToastUtil.showBottomSuccess("暂无更多"); layout.finishLoadMore();
mActivity.refreshLayout.setEnableRefresh(false); } else layout.finishLoadMoreWithNoMoreData();
return; } else ToastUtil.show(R.getMsg());
} }
requestList.addAll(0, data);
mActivity.mAdapter.loadHistory(data);
current = current + 1;
if (data.size() < size){
ToastUtil.showBottomSuccess("已加载全部聊天数据");
mActivity.refreshLayout.setEnableRefresh(false);
}
}else ToastUtil.showBottomWarn(R.getMsg());
}
@Override @Override
public void onError(Throwable e) { public void onError(Throwable e) {
mActivity.refreshLayout.finishRefresh(false); layout.finishLoadMore(false);
ExceptionHandle.baseExceptionMsg(e); ExceptionHandle.baseExceptionMsg(e);
} }
@Override @Override
public void onComplete() { public void onComplete() {}
/** 完成刷新 */ });
mActivity.refreshLayout.finishRefresh();
}
});
} }
} }

BIN
app/src/main/res/drawable-xxhdpi/skin_messages_right_bubble_highlighted.9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 599 B

0
app/src/main/res/drawable-xxhdpi/skin_messages_right_bubble.9.png → app/src/main/res/drawable-xxhdpi/skin_messages_right_bubble_wechat.9.png

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

6
app/src/main/res/drawable/skin_messages_right_bubble.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/skin_messages_right_bubble_highlighted" />
<item android:drawable="@drawable/skin_messages_right_bubble_wechat" />
</selector>

71
app/src/main/res/layout/activity_instant.xml

@ -7,51 +7,53 @@
<data> <data>
<variable name="viewModel" type="com.kanglai.push.ui.vm.InstantViewModel" /> <variable name="viewModel" type="com.kanglai.push.ui.vm.InstantViewModel" />
</data> </data>
<RelativeLayout <LinearLayout
android:background="#F3F4F6" android:background="#F3F4F6"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<!-- 顶部任务栏 -->
<include <include
android:id="@+id/layout_toolbar" android:id="@+id/layout_toolbar"
layout="@layout/layout_toolbar" layout="@layout/layout_toolbar"
binding:toolbarViewModel="@{viewModel.toolbarViewModel}" /> binding:toolbarViewModel="@{viewModel.toolbarViewModel}" />
<!-- 消息刷新布局 -->
<com.scwang.smart.refresh.layout.SmartRefreshLayout <com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/instant_smart_refresh" android:id="@+id/instant_smart_refresh"
tools:ignore="MissingClass" android:layout_width="match_parent"
android:layout_below="@+id/layout_toolbar" android:layout_height="0dp"
android:layout_above="@+id/layout_footer" android:layout_weight="1"
android:layout_height="match_parent" android:scaleY="-1"
android:layout_width="match_parent"> app:srlEnableRefresh="false"
app:srlEnableAutoLoadMore="false"
app:srlEnableNestedScrolling="false">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/instant_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:scrollbars="none"
android:fadeScrollbars="false"
android:dividerHeight="0dp"
android:divider="@android:color/transparent"
tools:itemCount="1"
android:scaleY="-1"
tools:listitem="@layout/item_chat_room"/>
<com.scwang.smart.refresh.header.ClassicsHeader <com.scwang.smart.refresh.header.ClassicsHeader
android:id="@+id/instant_smart_header" android:id="@+id/instant_smart_header"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:srlTextPulling="@string/instant_header_pulling" android:scaleY="-1"
app:srlTextLoading="@string/instant_header_load" app:srlTextPulling="下拉加载更多"/>
app:srlTextRelease="@string/instant_header_release"
app:srlTextFinish="@string/instant_header_finish"
app:srlTextFailed="@string/instant_header_fail"
app:srlPrimaryColor="@color/common_app_them"
app:srlAccentColor="@android:color/white"/>
<androidx.recyclerview.widget.RecyclerView
android:overScrollMode="never"
android:id="@+id/instant_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</com.scwang.smart.refresh.layout.SmartRefreshLayout> </com.scwang.smart.refresh.layout.SmartRefreshLayout>
<LinearLayout <LinearLayout
android:id="@+id/layout_footer" android:id="@+id/layout_footer"
android:background="@color/white" android:background="@color/white"
android:layout_alignParentBottom="true"
android:orientation="vertical" android:orientation="vertical"
android:padding="5dip"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
<!-- 输入框 --> android:gravity="center_vertical">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -60,8 +62,8 @@
android:gravity="center_vertical"> android:gravity="center_vertical">
<ImageView <ImageView
android:id="@+id/iv_more_line" android:id="@+id/iv_more_line"
android:layout_marginLeft="@dimen/dp_2" android:layout_marginStart="@dimen/dp_2"
android:layout_marginRight="@dimen/dp_7" android:layout_marginEnd="@dimen/dp_7"
android:src="@drawable/icon_btn_add_line" android:src="@drawable/icon_btn_add_line"
android:background="?attr/selectableItemBackgroundBorderless" android:background="?attr/selectableItemBackgroundBorderless"
android:layout_width="@dimen/dp_32" android:layout_width="@dimen/dp_32"
@ -69,8 +71,8 @@
<ImageView <ImageView
android:visibility="gone" android:visibility="gone"
android:id="@+id/iv_more_fill" android:id="@+id/iv_more_fill"
android:layout_marginLeft="@dimen/dp_2" android:layout_marginStart="@dimen/dp_2"
android:layout_marginRight="@dimen/dp_7" android:layout_marginEnd="@dimen/dp_7"
android:src="@drawable/icon_btn_add_fill" android:src="@drawable/icon_btn_add_fill"
android:background="?attr/selectableItemBackgroundBorderless" android:background="?attr/selectableItemBackgroundBorderless"
android:layout_width="@dimen/dp_32" android:layout_width="@dimen/dp_32"
@ -87,7 +89,9 @@
android:layout_weight="1" android:layout_weight="1"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/instant_message_input_box"/> android:background="@drawable/instant_message_input_box"
android:autofillHints="msg"
tools:ignore="LabelFor" />
<TextView <TextView
android:id="@+id/instant_send_btn" android:id="@+id/instant_send_btn"
android:text="发 送" android:text="发 送"
@ -95,11 +99,12 @@
android:textColor="@color/white" android:textColor="@color/white"
android:gravity="center" android:gravity="center"
android:background="@drawable/icon_btn_primary_radius_bg" android:background="@drawable/icon_btn_primary_radius_bg"
android:layout_marginLeft="@dimen/dp_5" android:layout_marginStart="@dimen/dp_5"
android:layout_marginRight="@dimen/dp_2" android:layout_marginEnd="@dimen/dp_2"
android:layout_width="@dimen/dp_50" android:layout_width="@dimen/dp_50"
android:layout_height="@dimen/dp_34" android:layout_height="@dimen/dp_34"
binding:onClickCommand="@{viewModel.sendMsgClickCommand}"/> binding:onClickCommand="@{viewModel.sendMsgClickCommand}"
tools:ignore="SpUsage" />
</LinearLayout> </LinearLayout>
<!-- 其他操作 --> <!-- 其他操作 -->
<GridLayout <GridLayout
@ -142,5 +147,5 @@
</GridLayout> </GridLayout>
</LinearLayout> </LinearLayout>
</RelativeLayout> </LinearLayout>
</layout> </layout>

165
app/src/main/res/layout/item_chat_room.xml

@ -2,125 +2,126 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:padding="@dimen/dp_10">
android:layout_height="wrap_content">
<!-- 发送时间 -->
<TextView <TextView
android:id="@+id/tv_send_time" android:id="@+id/tv_send_time"
android:text="08:00"
android:textColor="@color/black50"
android:textSize="@dimen/sp_12"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
<!-- 左边消息 --> android:layout_marginBottom="5dp"
<LinearLayout android:text="@string/app_name"
android:textSize="@dimen/sp_8"
android:paddingLeft="3dip"
android:paddingRight="3dip"
android:textColor="#aaaaaa"/>
<RelativeLayout
android:id="@+id/layout_chatting_left" android:id="@+id/layout_chatting_left"
android:layout_marginTop="@dimen/dp_5" android:layout_width="fill_parent"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content"> android:layout_marginTop="5dp" >
<!-- 左侧头像 -->
<ImageView <ImageView
android:id="@+id/iv_avatar_left" android:id="@+id/iv_avatar_left"
android:layout_width="@dimen/dp_40" android:layout_width="@dimen/dp_38"
android:layout_height="@dimen/dp_40" android:layout_height="@dimen/dp_38"
android:layout_marginTop="@dimen/dp_10" android:layout_alignParentTop="true"
android:layout_marginLeft="@dimen/dp_10" android:src="@drawable/icon_links_avatar"
android:src="@drawable/icon_links_avatar"/> android:focusable="false"/>
<!-- 左侧聊天框 -->
<LinearLayout <LinearLayout
android:id="@+id/chatting_frame_left" android:id="@+id/chatting_frame_left"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_10" android:layout_marginStart="10dp"
android:gravity="left" android:layout_marginEnd="55dp"
android:minWidth="@dimen/dp_60" android:layout_toEndOf="@+id/iv_avatar_left"
android:gravity="center"
android:minWidth="60dp"
android:background="@drawable/skin_messages_left_bubble" android:background="@drawable/skin_messages_left_bubble"
android:orientation="vertical"> android:orientation="vertical">
<FrameLayout <FrameLayout
android:layout_margin="@dimen/dp_2" android:layout_margin="2dp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"> android:layout_height="match_parent"
tools:ignore="UselessParent">
<ImageView
android:id="@+id/chatting_left_img"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="@string/app_name"
tools:src="@mipmap/ico_dialogx_error"/>
<TextView <TextView
android:id="@+id/chatting_left_text" android:id="@+id/chatting_left_text"
android:layout_margin="5dp"
android:textSize="@dimen/sp_13"
android:textStyle="bold"
android:singleLine="false" android:singleLine="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dp_5"
android:gravity="left"
android:layout_gravity="center" android:layout_gravity="center"
android:maxWidth="@dimen/dp_230" android:gravity="start"
android:layout_alignParentEnd="true" android:textColor="#444444"
android:text="都可以使用RippleDrawable来达到水波纹特效,而且必须处于可点击状态," android:text="@string/app_name"
android:textSize="@dimen/sp_14"/> android:layout_height="wrap_content"
android:layout_width="wrap_content"/>
</FrameLayout> </FrameLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </RelativeLayout>
<!-- 右边消息 -->
<LinearLayout <RelativeLayout
android:id="@+id/layout_chatting_right" android:id="@+id/layout_chatting_right"
android:layout_marginTop="@dimen/dp_5" android:layout_width="fill_parent"
android:gravity="end" android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_marginTop="5dp" >
android:layout_height="wrap_content"> <ImageView
<!-- 右侧聊天框 --> android:id="@+id/iv_avatar_right"
android:layout_width="@dimen/dp_38"
android:layout_height="@dimen/dp_38"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:src="@drawable/icon_links_avatar"
android:focusable="false"/>
<LinearLayout <LinearLayout
android:id="@+id/chatting_frame_right" android:id="@+id/chatting_frame_right"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_10" android:layout_marginStart="55dp"
android:gravity="center" android:layout_marginEnd="10dp"
android:maxWidth="@dimen/dp_60" android:layout_toStartOf="@+id/iv_avatar_right"
android:background="@drawable/skin_messages_right_bubble" android:background="@drawable/skin_messages_right_bubble"
android:gravity="center"
android:minWidth="60dp"
android:orientation="vertical"> android:orientation="vertical">
<FrameLayout <FrameLayout
android:layout_margin="@dimen/dp_2" android:layout_margin="2dp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
tools:ignore="UselessParent">
<ImageView
android:visibility="visible"
android:id="@+id/chatting_right_img"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="@string/app_name"
tools:src="@mipmap/ico_dialogx_error"/>
<TextView <TextView
android:id="@+id/chatting_rigth_text" android:id="@+id/chatting_right_text"
android:layout_margin="5dp"
android:textSize="@dimen/sp_13"
android:textStyle="bold"
android:singleLine="false" android:singleLine="false"
android:maxWidth="@dimen/dp_230"
android:gravity="right"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_width="wrap_content" android:gravity="right"
android:textColor="#444444"
android:text="@string/app_name"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="@dimen/dp_5" android:layout_width="wrap_content"
android:text="测试内容,任何view处于可点击状态,都可以使用RippleDrawable来达到水波纹特效,而且必须处于可点击状态,才会出现波纹动画效果" tools:ignore="RtlHardcoded" />
android:textSize="@dimen/sp_14"/>
</FrameLayout> </FrameLayout>
</LinearLayout> </LinearLayout>
<!-- 右侧头像 --> </RelativeLayout>
<ImageView
android:id="@+id/iv_avatar_right"
android:layout_width="@dimen/dp_40"
android:layout_height="@dimen/dp_40"
android:layout_marginTop="@dimen/dp_10"
android:layout_marginRight="@dimen/dp_5"
android:src="@drawable/icon_links_avatar"/>
</LinearLayout>
<!-- 系统消息内容 默认隐藏 -->
<TextView
android:visibility="gone"
android:id="@+id/tv_system_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="@dimen/dp_10"
android:textColor="#eeeeee"
android:textSize="@dimen/sp_12"
android:text="系统消息"
android:background="@drawable/icon_btn_swipeable_bg1"
android:paddingTop="@dimen/dp_2"
android:paddingBottom="@dimen/dp_2"
android:paddingLeft="@dimen/dp_5"
android:paddingRight="@dimen/dp_5"/>
</LinearLayout> </LinearLayout>
Loading…
Cancel
Save