效果:
MatchListLayout
package com.coral3.ah.components;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemChildClickListener;
import com.coral3.ah.adapter.RvAdapterChatList;
import com.coral3.ah.adapter.RvAdapterMatchList;
import com.coral3.ah.entity.bo.ChatListItemBO;
import com.coral3.common_module.R;
import com.coral3.common_module.utils.LogUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class MatchListLayout extends LinearLayout implements BaseQuickAdapter.RequestLoadMoreListener{
private Context mContext;
private View view;
// 列表相关
private RecyclerView rv;
private RvAdapterMatchList rvAdapter;
private List<ChatListItemBO> data = new ArrayList<>();
private Callback callback;
public MatchListLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mContext = context;
initView();
initListener();
}
private void initView() {
view = LayoutInflater.from(mContext).inflate(R.layout.layout_list, this);
initRv();
}
private void initListener(){
rvAdapter.setOnLoadMoreListener(this, rv);
rvAdapter.setOnItemClickListener((adapter, view, position) -> {
if(callback != null) callback.onItemClick(data.get(position), data, view, position);
});
//子控件点击监听
rvAdapter.setOnItemChildClickListener((adapter, view, position) -> {
});
rvAdapter.setOnItemLongClickListener((adapter, view, position) -> {
if(callback != null) callback.onItemLongClick(data.get(position), data, view, position);
return true;
});
}
public void setCallback(Callback callback){
this.callback = callback;
}
private void initRv() {
rv = view.findViewById(R.id.recyclerview);
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
//设置布局管理器
rv.setLayoutManager(layoutManager);
rvAdapter = new RvAdapterMatchList(R.layout.layout_recyclerview_item_match_list, data);
rv.setAdapter(rvAdapter);
}
@Override
public void onLoadMoreRequested() {
LogUtil.d("加载更多...");
callback.onLoadMoreRequested();
}
public List<ChatListItemBO> getData(){
return data;
}
public void loadMoreComplete(){
rvAdapter.loadMoreComplete();
}
public void loadMoreEnd(){
rvAdapter.loadMoreEnd();
}
public void clearData(){
data.clear();
rvAdapter.notifyDataSetChanged();
}
public void setData(ChatListItemBO item){
data.add(item);
LogUtil.d("ChatListItemBO:" + item.toString());
rvAdapter.notifyDataSetChanged();
}
public RvAdapterMatchList getAdapter(){
return rvAdapter;
}
public interface Callback{
void onItemClick(ChatListItemBO model, List<ChatListItemBO> data, View view, int position);
void onItemTvActionClick(ChatListItemBO model, List<ChatListItemBO> data, View view, int position);
void onItemLongClick(ChatListItemBO model, List<ChatListItemBO> data, View view, int position);
void onLoadMoreRequested();
}
}
RvAdapterMatchList
package com.coral3.ah.adapter;
import android.text.TextUtils;
import android.view.View;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.chad.library.adapter.base.loadmore.LoadMoreView;
import com.coral3.ah.entity.bo.ChatListItemBO;
import com.coral3.common_module.R;
import com.coral3.common_module.base.BaseBuildInfo;
import com.coral3.common_module.entity.type.ChatMsgStatus;
import com.coral3.common_module.utils.GlideUtil;
import com.coral3.common_module.utils.TimeUtil;
import java.util.List;
public class RvAdapterMatchList extends BaseQuickAdapter<ChatListItemBO, BaseViewHolder> {
public RvAdapterMatchList(int layoutResId, @Nullable List<ChatListItemBO> data) {
super(layoutResId, data);
this.setLoadMoreView(new LoadMoreView() {
@Override
public int getLayoutId() {
//自己想要显示的加载更多布局样式
return R.layout.layout_custom_bottom_loading_chat_list;
}
@Override
protected int getLoadingViewId() {
//加载中...
return R.id.tv_loading;
}
@Override
protected int getLoadFailViewId() {
//加载错误...
return R.id.tv_loading_err;
}
@Override
protected int getLoadEndViewId() {
//加载结束
return R.id.tv_loading_end;
}
});
}
@Override
protected void convert(BaseViewHolder helper, ChatListItemBO item) {
if (!TextUtils.isEmpty(item.getImageUrl())) {
GlideUtil.loadImgRound(mContext, BaseBuildInfo.BASE_URL + "/" + BaseBuildInfo.CONTEXT + "/avatar/" + item.getImageUrl(), helper.getView(R.id.iv_img_view));
}
helper.setText(R.id.tv_base_name, item.getName());
helper.setText(R.id.tv_base_content, item.getContent());
helper.setText(R.id.tv_base_date, TimeUtil.AHFormatTime(item.getTime()));
}
}
TabbThiFragment
package com.coral3.ah.ui.fragment.tabbar;
import android.app.Activity;
import android.net.NetworkInfo;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.coral3.ah.R;
import com.coral3.ah.adapter.RvAdapterChatList;
import com.coral3.ah.adapter.RvAdapterMatchList;
import com.coral3.ah.components.ChatListLayout;
import com.coral3.ah.components.MatchListLayout;
import com.coral3.ah.entity.bo.ChatListItemBO;
import com.coral3.cim_module.CIMEventListener;
import com.coral3.cim_module.CIMListenerManager;
import com.coral3.cim_module.constant.CIMConstant;
import com.coral3.cim_module.model.Message;
import com.coral3.cim_module.model.ReplyBody;
import com.coral3.cim_module.model.SentBody;
import com.coral3.common_module.base.BaseBuildInfo;
import com.coral3.common_module.base.BasePO;
import com.coral3.common_module.base.BasePagingBean;
import com.coral3.common_module.components.CustomDialog;
import com.coral3.common_module.components.PopWinLayout;
import com.coral3.common_module.constant.ChatConstants;
import com.coral3.common_module.constant.RouterActionConstants;
import com.coral3.common_module.constant.StoreConstants;
import com.coral3.common_module.db.MsgDBHelper;
import com.coral3.common_module.entity.po.ChatGroupDetailPO;
import com.coral3.common_module.entity.po.MsgGroupPO;
import com.coral3.common_module.entity.type.ChatMsgStatus;
import com.coral3.common_module.entity.type.ChatOriginType;
import com.coral3.common_module.entity.type.ChatType;
import com.coral3.common_module.entity.type.IntentionType;
import com.coral3.common_module.entity.type.MediaType;
import com.coral3.common_module.model.PopModel;
import com.coral3.common_module.utils.GlideUtil;
import com.coral3.common_module.utils.LogUtil;
import com.coral3.common_module.utils.TimeUtil;
import com.coral3.common_module.utils.ToastUtil;
import com.coral3.common_module.utils.WinManagerUtil;
import com.coral3.router_module.YRouter;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import static com.coral3.common_module.constant.ChatConstants.CHAT_DB_VERSION;
import static com.coral3.common_module.constant.ChatConstants.CHAT_GROUP_ID;
import static com.coral3.common_module.constant.ChatConstants.CHAT_TYPE;
import static com.coral3.common_module.constant.ChatConstants.CHAT_WHERE;
/**
* @description工作列表
* @author WTY
*/
public class TabbThiFragment extends Fragment implements MatchListLayout.Callback {
private View root;
private Activity mActivity;
private MatchListLayout matchListLayout;
private PopWinLayout popLayout;
private LinearLayout popDelBtn;
private int longPressPos;
private CustomDialog customDialog;
private int pageNo = 0;
private int pageSize = 15;
public TabbThiFragment() {
// Required empty public constructor
}
private void initListener() {
popDelBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
customDialog = new CustomDialog(mActivity);
customDialog.setTitle("移除")
.setMCancelable(false)
.setContent("是否彻底移除此条记录")
.setCancel("取消", new CustomDialog.IOnCancelListener() {
@Override
public void onCancel(CustomDialog customDialog) {
customDialog.dismiss();
}
})
.setComfirm("确定", new CustomDialog.IOnComfirmListener() {
@Override
public void onConfirm(CustomDialog customDialog) {
if (longPressPos != -1) {
handleRemoveMsg(longPressPos);
popLayout.hidePopView();
}
}
}).show();
}
});
}
public static TabbThiFragment newInstance(String param1) {
TabbThiFragment fragment = new TabbThiFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
public static TabbThiFragment newInstance() {
TabbThiFragment fragment = new TabbThiFragment();
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (root == null) root = inflater.inflate(R.layout.fragment_seek_friend, container, false);
matchListLayout = root.findViewById(R.id.chat_list);
matchListLayout.setCallback(this);
mActivity = getActivity();
popLayout = new PopWinLayout(mActivity, null);
List<PopModel> msgPopData = new ArrayList<>();
msgPopData.add(new PopModel(R.mipmap.msg, "移除"));
popLayout.setData(msgPopData);
popLayout.setTriangleCenter();
// 设置自定义布局
popLayout.setCustomView(0);
popDelBtn = popLayout.findViewById(R.id.ll_del);
TextView tvView = popLayout.findViewById(R.id.tv_del);
tvView.setText("移除");
initListener();
getData();
return root;
}
private void getData() {
if(matchListLayout.getAdapter().getData().size() > 80) {
matchListLayout.loadMoreEnd();
return;
}
TimeUtil.setTimeout(() -> {
for (int i = 0; i < 20; i++) {
ChatListItemBO chatListItemBO = new ChatListItemBO();
chatListItemBO.setName(i + "");
chatListItemBO.setContent(i + getRandomString((int)(Math.random()*100)));
chatListItemBO.setTime(1000000l);
matchListLayout.setData(chatListItemBO);
}
matchListLayout.loadMoreComplete();
}, 1000);
}
//length用户要求产生字符串的长度
public static String getRandomString(int length){
String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random=new Random();
StringBuffer sb=new StringBuffer();
for(int i=0;i<length;i++){
int number=random.nextInt(62);
sb.append(str.charAt(number));
}
return sb.toString();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
private void handleRemoveMsg(int longPressPos) {
RvAdapterMatchList adapter = matchListLayout.getAdapter();
List<ChatListItemBO> data = matchListLayout.getData();
adapter.notifyItemChanged(longPressPos);
adapter.notifyItemRangeRemoved(longPressPos, data.size() - longPressPos);
adapter.notifyDataSetChanged();
customDialog.dismiss();
ToastUtil.showMsg(mActivity, "已移除");
}
@Override
public void onItemClick(ChatListItemBO chatListItemBO, List<ChatListItemBO> data, View view, int position) {
if (!TextUtils.isEmpty(chatListItemBO.getGroupId())) {
LinearLayout llMsgDot = view.findViewById(R.id.ll_msg_dot);
llMsgDot.setVisibility(View.INVISIBLE);
MsgGroupPO msgGroupPO = new MsgGroupPO();
msgGroupPO.group_avatar = chatListItemBO.getImageUrl();
msgGroupPO.is_read = ChatMsgStatus.READ.getCode();
msgGroupPO.group_id = chatListItemBO.getGroupId();
msgGroupPO.group_name = chatListItemBO.getName();
msgGroupPO.update_time = chatListItemBO.getTime();
msgGroupPO.short_msg = chatListItemBO.getContent();
msgGroupPO.del_flag = BasePO.Delete.NORMAL.getCode();
}
YRouter.getInstance(mActivity)
.withInt(CHAT_WHERE, ChatOriginType.LIST_ENTER.getCode())
.withString(CHAT_GROUP_ID, chatListItemBO.getGroupId())
.withString(ChatConstants.TARGET_ID, chatListItemBO.getTarget_id())
.withString(ChatConstants.CHAT_TITLE, chatListItemBO.getName())
.withString(ChatConstants.SEND_ID, chatListItemBO.getSender_id())
.withInt(CHAT_TYPE, ChatType.DOUBLE_CHAT.getCode())
.build(RouterActionConstants.MATCH_TARGET_DETAIL)
.go();
}
@Override
public void onItemTvActionClick(ChatListItemBO chatListItemBO, List<ChatListItemBO> data, View view, int position) {
LogUtil.d("聊天列表参数:" + chatListItemBO.toString());
if (!TextUtils.isEmpty(chatListItemBO.getGroupId())) {
LinearLayout llMsgDot = view.findViewById(R.id.ll_msg_dot);
llMsgDot.setVisibility(View.INVISIBLE);
// 更双聊消息状态
MsgGroupPO msgGroupPO = new MsgGroupPO();
msgGroupPO.group_avatar = chatListItemBO.getImageUrl();
msgGroupPO.is_read = ChatMsgStatus.READ.getCode();
msgGroupPO.group_id = chatListItemBO.getGroupId();
msgGroupPO.group_name = chatListItemBO.getName();
msgGroupPO.update_time = chatListItemBO.getTime();
msgGroupPO.short_msg = chatListItemBO.getContent();
msgGroupPO.del_flag = BasePO.Delete.NORMAL.getCode();
}
YRouter.getInstance(mActivity)
.withInt(CHAT_WHERE, ChatOriginType.LIST_ENTER.getCode())
.withString(CHAT_GROUP_ID, chatListItemBO.getGroupId())
.withString(ChatConstants.TARGET_ID, chatListItemBO.getTarget_id())
.withString(ChatConstants.CHAT_TITLE, chatListItemBO.getName())
.withString(ChatConstants.SEND_ID, chatListItemBO.getSender_id())
.withInt(CHAT_TYPE, ChatType.DOUBLE_CHAT.getCode())
.build(RouterActionConstants.CHAT)
.go();
}
@Override
public void onItemLongClick(ChatListItemBO model, List<ChatListItemBO> data, View view, int position) {
longPressPos = position;
popLayout.setDropDownBtn(view);
int[] location = new int[2]; // 定义坐标存储对象
view.getLocationOnScreen(location); // 获取坐标
int y = location[1]; // y轴坐标
int screenHeightHalf = WinManagerUtil.getHeight(mActivity) >> 1; // 获取屏幕一半的尺寸
if (y < screenHeightHalf) { // 向下展示
popLayout.showPopView(view);
} else { // 向上展示
popLayout.showPopViewAsUp(view);
}
}
@Override
public void onLoadMoreRequested() {
pageNo++;
getData();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onResume() {
super.onResume();
pageNo = 0;
}
}
layout_recyclerview_item_match_list
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_weight="1"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:background="#F40"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="70dp"
android:gravity="center_vertical"
android:layout_height="wrap_content">
<ImageView
android:src="@mipmap/chat_group_def_avatar"
android:id="@+id/iv_img_view"
android:layout_width="60dp"
android:layout_height="60dp"
android:scaleType="centerCrop"/>
<LinearLayout
android:id="@+id/ll_msg_dot"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="-2dp"
android:visibility="invisible"
android:layout_marginTop="3dp">
<TextView
android:layout_width="10dp"
android:layout_height="wrap_content"
android:background="@drawable/msg_dot"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/ll_title"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<TextView
android:text="标题"
android:id="@+id/tv_base_name"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="18sp"
android:ellipsize="end"
android:textStyle="bold"
android:singleLine="true"
android:gravity="center_vertical"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:id="@+id/tv_base_date"
android:textSize="13sp"
android:gravity="end|center"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:text="内容"
android:id="@+id/tv_base_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>