以前写过一个上拉下拉的控件,经过改版之后,有了这篇博客,代码更简洁了,容易理解了。
先上xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:id="@+id/id_refresh_layout"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/id_refresh_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/id_loadMore_view"
android:background="@color/line_grey"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
然后重写LinearLayout,
/**
* @Author Lee
* @Date 创建时间 2017/11/9
* @Description 可以时间上拉加载下拉刷新的控件
* @Version 1.0.0
*/
public class RefreshRecyclerView extends LinearLayout {
private SwipeRefreshLayout RefreshDataView;//下拉刷新控件
private RecyclerView LoadMoreDataView;//上拉加载控件
private int LastVisibleItemPosition;//最后一个可见的item位置
private int PageIndex = 0;//当前的页码
private boolean IsCanLoadData = true;//可以加载数据
public RefreshRecyclerView(Context context) {
super(context);
View view = LayoutInflater.from(context).
inflate(R.layout.refresh_recycler_view, this, true);
__init(view);
}
public RefreshRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
View view = LayoutInflater.from(context).
inflate(R.layout.refresh_recycler_view, this, true);
__init(view);
}
public RefreshRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
View view = LayoutInflater.from(context).
inflate(R.layout.refresh_recycler_view, this, true);
__init(view);
}
//初始化控件--双下滑是公司要求,按照自己的方法命名就好
private void __init(View view) {
//Google自带的下拉刷新
RefreshDataView = (SwipeRefreshLayout)view.findViewById(R.id.id_refresh_view);
RefreshDataView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refreshData();
}
});
//监听RecyclerView 的Scroll事件
LoadMoreDataView = (RecyclerView)view.findViewById(R.id.id_loadMore_view);
LoadMoreDataView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
//网上给的都是有下拉圈圈的,老板要求一个无刷新提示的,不过很菜,下拉快了依旧有卡顿现象,欢迎大神给指点
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
//这里是网上搜到的判断不同布局最后一个的可见位置的方法--为了方便以后重写
if (layoutManager instanceof GridLayoutManager) {
LastVisibleItemPosition = ((GridLayoutManager)layoutManager).
findLastVisibleItemPosition();
}
else if (layoutManager instanceof StaggeredGridLayoutManager) {
int[] into = new int[((StaggeredGridLayoutManager)layoutManager).
getSpanCount()];
((StaggeredGridLayoutManager)layoutManager).findLastVisibleItemPositions(into);
LastVisibleItemPosition = findMax(into);
}
else {
LastVisibleItemPosition = ((LinearLayoutManager)layoutManager).
findLastVisibleItemPosition();
}
//上拉滑动距离大于0,当然也可以设置更多, 可见位置判断最后一个加1,(因为加了个底部,提示已经没有了)
if (LastVisibleItemPosition + 1 >= recyclerView.getLayoutManager().getItemCount()
&& dy >= 0) {
getAndLoadDatas();
}
}
});
}
private int findMax(int[] lastPositions) {
int max = lastPositions[0];
for (int value : lastPositions) {
if (value > max) {
max = value;
}
}
return max;
}
//获取方法
public LRecyclerViewAdapter getAdapter() {
return (LRecyclerViewAdapter) LoadMoreDataView.getAdapter();
}
//提供给使用者设置的方法
public void setAdapter(LRecyclerViewAdapter adapter) {
LoadMoreDataView.setAdapter(adapter);
}
public void setLayoutManager(LinearLayoutManager layoutManager) {
LoadMoreDataView.setLayoutManager(layoutManager);
}
//加载更多方法
private void getAndLoadDatas() {
if (!IsCanLoadData) {
return;
}
IsCanLoadData = false;
//传入当前的页码
getAdapter().getDatas(getLoadPageIndex(), new LRecyclerViewAdapter.IOnData() {
@Override
public void onData(List datas) {
//AssertUtil一个判断是否为空的工具类,网上百度一个就行
if (AssertUtil.isEmpty(datas) && !isFullScreen()) {
getAdapter().setFootShow(true);
}
else {
getAdapter().setFootShow(false);
}
RefreshDataView.setRefreshing(false);
if (AssertUtil.isNotEmpty(datas)) {
IsCanLoadData = true;
getAdapter().appendData(datas);
}
}
});
}
//判断是否满一屏幕的方法
private boolean isFullScreen() {
return LoadMoreDataView.computeVerticalScrollExtent() >=
LoadMoreDataView.computeVerticalScrollRange();
}
private int getLoadPageIndex() {
return ++PageIndex;
}
//提供外界刷新自主刷新的方法
public void refreshData() {
PageIndex = 0;
getAdapter().clearData();
IsCanLoadData = true;
getAndLoadDatas();
}
}
上面有详细的注释了;
最后就是adapter,在这里我重新了一下adapter
/**
* @Author Lee
* @Date 创建时间 2017/11/9
* @Description
* @Version
*/
public abstract class LRecyclerViewAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int VIEW_TYPE_FOOTER = 0;//加载底部数据
private static final int VIEW_TYPE_ITEM = 1;//加载普通数据
private static final int FOOTER_SHOW = 0;//底部显示
private static final int FOOTER_HIDE = 1;//底部隐藏
private int NowFooterStatus = FOOTER_HIDE;
private List<T> LoadData;
protected LayoutInflater Infalter;
public LRecyclerViewAdapter(Context context, List<T> loadData) {
Infalter = LayoutInflater.from(context);
this.LoadData = loadData;
}
//加载布局
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_FOOTER) {
return new LRecyclerViewAdapter.FooterViewHolder(Infalter.inflate(R.layout.footer_layout, parent, false));
}
else if (viewType == VIEW_TYPE_ITEM) {
return setItemVH(parent);
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(getItemViewType(position) == VIEW_TYPE_ITEM) {
onBindItemViewHolder(holder, position);
}
else {
onBindFooterViewHolder(holder, NowFooterStatus);
}
}
private void onBindFooterViewHolder(RecyclerView.ViewHolder holder, int loadStatus) {
final LRecyclerViewAdapter.FooterViewHolder footerViewHolder = (LRecyclerViewAdapter.FooterViewHolder)holder;
if (loadStatus == FOOTER_SHOW) {
footerViewHolder.mLoadingLayout.setVisibility(View.VISIBLE);
delayedSetFooterGone(footerViewHolder);
}
else {
footerViewHolder.mLoadingLayout.setVisibility(View.GONE);
}
}
private void delayedSetFooterGone(final LRecyclerViewAdapter.FooterViewHolder footerViewHolder) {
new Handler().postDelayed(new Runnable() {
public void run() {
NowFooterStatus = FOOTER_HIDE;
footerViewHolder.mLoadingLayout.setVisibility(View.GONE);
}
}, 2000);
}
//得到总数
@Override
public int getItemCount() {
return LoadData.size() + 1;
}
@Override
public int getItemViewType(int position) {
if (position + 1 == getItemCount()) {
return VIEW_TYPE_FOOTER;
}
return VIEW_TYPE_ITEM;
}
public class FooterViewHolder extends RecyclerView.ViewHolder {
public LinearLayout mLoadingLayout;
public FooterViewHolder(View itemView) {
super(itemView);
mLoadingLayout = (LinearLayout) itemView.findViewById(R.id.id_loading_layout);
}
}
void setData(List<T> data) {
LoadData.clear();
LoadData.addAll(data);
this.notifyDataSetChanged();
}
void appendData(List<T> data) {
LoadData.addAll(data);
this.notifyDataSetChanged();
}
void clearData() {
LoadData.clear();
this.notifyDataSetChanged();
}
void setFootShow(boolean show) {
NowFooterStatus = show ? FOOTER_SHOW : FOOTER_HIDE;
}
public interface IOnData<T> {
void onData(List<T> datas);
}
public abstract void onBindItemViewHolder(final RecyclerView.ViewHolder holder, int position);
public abstract RecyclerView.ViewHolder setItemVH(ViewGroup parent);
public abstract void getDatas(int pageIndex, final IOnData back);
}
上面这个可以复制过去直接使用,当然你需要继承这个类来重写其中的一些方法。
之后就是最后的步骤了。:
初始化Adapter
DeliverAdapter = new DeliverAddressAdapter(DeliveryAddressListActivity.this, new
ArrayList<DeliveryAddress>());
//素质三连,初始化,放adapter,放LayoutManager
LayoutManager = new LinearLayoutManager(DeliveryAddressListActivity.this);
RefreshRecycler = (RefreshRecyclerView)findViewById(R.id.receiver);
RefreshRecycler.setAdapter(DeliverAdapter);
RefreshRecycler.setLayoutManager(LayoutManager);
实现自己的adapter就可以了,代码如下:
class DeliverAddressAdapter extends LRecyclerViewAdapter<DeliveryAddress> {
private List<DeliveryAddress> DeliveryAddress;
public DeliverAddressAdapter(Context context, List<DeliveryAddress> loadData) {
super(context, loadData);
this.DeliveryAddress = loadData;
}
@Override
public void onBindItemViewHolder(RecyclerView.ViewHolder holder,final int position) {
final DeliverAddressVH deliverAddressVH = (DeliverAddressVH)holder;
deliverAddressVH.id_da_address.setText(DeliveryAddress.get(position).
getDa_address());
deliverAddressVH.id_da_consignee.setText(DeliveryAddress.get(position).
getDa_consignee());
deliverAddressVH.id_mobile_phone.setText(DeliveryAddress.get(position).
getDa_consigneetelephone());
deliverAddressVH.id_address_del.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (position >= 0 && position < DeliveryAddress.size()) {
final int da_id = DeliveryAddress.get(position).getDa_id();
DeliveryAddress.remove(position);
deleteUserAddress(da_id);
if (position == 0) {
DeliverAdapter.notifyDataSetChanged();
}
else {
DeliverAdapter.notifyItemRemoved(position);//推荐用这个
}
}
}
});
deliverAddressVH.id_address_edit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (position >= 0 && position < DeliveryAddress.size()) {
Intent intent = new Intent(DeliveryAddressListActivity.this,
DeliveryAddressEditActivity.class);
intent.putExtra("delivery", DeliveryAddress.get(position));
startActivityForResult(intent, 1);
}
}
});
}
@Override
public RecyclerView.ViewHolder setItemVH(ViewGroup parent) {
return new DeliverAddressVH(Infalter.inflate(R.layout.delivery_address_item,
parent, false));
}
@Override
public void getDatas(int pageIndex, IOnData back) {
refreshdata(pageIndex, back);
}
public class DeliverAddressVH extends RecyclerView.ViewHolder {
TextView id_da_address;
TextView id_da_consignee;
TextView id_mobile_phone;
TextView id_address_del;
TextView id_address_edit;
public DeliverAddressVH(View itemView) {
super(itemView);
id_da_address = (TextView) itemView.findViewById(R.id.id_da_address);
id_da_consignee = (TextView) itemView.findViewById(R.id.id_da_consignee);
id_mobile_phone = (TextView) itemView.findViewById(R.id.id_mobile_phone);
id_address_del = (TextView) itemView.findViewById(R.id.id_address_del);
id_address_edit = (TextView) itemView.findViewById(R.id.id_address_edit);
}
}
}
以上的在继承的时候会要求重写,使用的时候两个类可以直接复制,布局文件就自己写吧,毕竟都不一样。