android实现瀑布流、上拉加载

效果:

请添加图片描述
请添加图片描述

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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值