LRecyclerViewActivity.java
/**
* <p> </p>
* Created by 行走的老者 on 2017/11/13 0013.
*/
public class LRecyclerViewActivity extends AppCompatActivity {
private LRecyclerView mLRecyclerView;
private TestAdapter mTestAdapter;
private SwipeRefreshLayout mRefreshLayout;
private List<String> mDataList;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lrecycler_view);
mLRecyclerView = findViewById(R.id.recycler_view);
mRefreshLayout = findViewById(R.id.switch_refresh);
mLRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mTestAdapter = new TestAdapter();
mLRecyclerView.setAdapter(mTestAdapter);
mRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
if (mLRecyclerView.isLoading()) {
mRefreshLayout.setRefreshing(false);
return;
}
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
mRefreshLayout.setRefreshing(false);
mDataList.add(0, "刷新.出來的數(shù)據(jù).....");
mTestAdapter.setDataList(mDataList);
}
});
}
}).start();
}
});
mDataList = new ArrayList<>();
for (int i = 0; i < 50; i++) {
mDataList.add("第一頁加載......" + i);
}
mTestAdapter.setDataList(mDataList);
mLRecyclerView.setOnLoadingListener(new LRecyclerView.OnLoadingListener() {
@Override
public void onLoading() {
if (mRefreshLayout.isRefreshing()) return;
mTestAdapter.setStatus(LoadingAdapter.STATUS_LOADING);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
mLRecyclerView.finishLoading();
mTestAdapter.setStatus(LoadingAdapter.STATUS_LOADED);
Log.i("liao", "......................mPage=" + mPage);
if (mPage > 4) {
Toast.makeText(LRecyclerViewActivity.this, "沒有更多數(shù)據(jù)了", Toast.LENGTH_SHORT).show();
return;
}
mPage++;
for (int i = 0; i < 50; i++) {
mDataList.add("上拉加載.出來的數(shù)據(jù)....." + i);
}
mTestAdapter.setDataList(mDataList);
}
});
}
}).start();
}
});
}
private int mPage = 1;
public class TestAdapter extends LoadingAdapter<String> {
@Override
public RecyclerView.ViewHolder onCreateHolder(ViewGroup parent, int viewType) {
return new ItemViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false));
}
@Override
protected void onBindHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof ItemViewHolder) {
ItemViewHolder itemViewHolder = (ItemViewHolder) holder;
itemViewHolder.mTextView.setText(mDataList.get(position));
}
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
TextView mTextView;
public ItemViewHolder(View itemView) {
super(itemView);
mTextView = itemView.findViewById(R.id.text);
}
}
}
}
xml資源
activity_lrecycler_view.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/switch_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<cn.jhworks.demo.loading.LRecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"/>
</android.support.v4.widget.SwipeRefreshLayout>
item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="60dp">
<TextView
android:id="@+id/text"
android:gravity="center"
android:text="helll"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
下面是上拉加載實(shí)現(xiàn)
實(shí)現(xiàn)見代碼:
LRecyclerView .java
/**
* <p> </p>
* Created by 行走的老者 on 2017/11/13 0013.
*/
public class LRecyclerView extends RecyclerView {
private boolean mIsLoading = false;
private int initPreItem = 3;
public LRecyclerView(Context context) {
this(context, null);
}
public LRecyclerView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public LRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
addOnScrollListener(mOnScrollListener);
}
public void finishLoading() {
mIsLoading = false;
}
public boolean isLoading() {
return mIsLoading;
}
private OnScrollListener mOnScrollListener = new OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
/* Log.i("liao", "newState=" + newState);
//第一種方式 有個(gè)bug:當(dāng)最后一個(gè)item剛顯示出來的時(shí)候停止滑動(dòng)這個(gè)時(shí)候也會(huì)觸發(fā)滑動(dòng)到底部的操作
LayoutManager layoutManager = getLayoutManager();
int itemCount = layoutManager.getItemCount();
int lastVisibleItemPosition = 0;
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
//得到這個(gè)數(shù)組后再取到數(shù)組中position值最大的那個(gè)就是最后顯示的position值了
int[] lastPositions = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions);
lastVisibleItemPosition = findMax(lastPositions);
}
if (!mIsLoading && ((lastVisibleItemPosition + 1) >= itemCount) && newState == SCROLL_STATE_IDLE) {
Log.i("liao", "加載.....lastVisibleItemPosition=" + lastVisibleItemPosition + ",itemCount=" + itemCount);
mIsLoading = true;
post(new Runnable() {
@Override
public void run() {
if (mOnLoadingListener != null) {
mOnLoadingListener.onLoading();
}
}
});
}*/
//第二種方式
//得到當(dāng)前顯示的最后一個(gè)item的view
View lastChildView = recyclerView.getLayoutManager().getChildAt(recyclerView.getLayoutManager().getChildCount() - 1);
//得到lastChildView的bottom坐標(biāo)值
int lastChildBottom = lastChildView.getBottom();
//得到Recycler view的底部坐標(biāo)減去底部padding值魁袜,也就是顯示內(nèi)容最底部的坐標(biāo)
int recyclerBottom = recyclerView.getBottom() - recyclerView.getPaddingBottom();
//通過這個(gè)lastChildView得到這個(gè)view當(dāng)前的position值
int lastPosition = recyclerView.getLayoutManager().getPosition(lastChildView);
//判斷l(xiāng)astChildView的bottom值跟recyclerBottom
//判斷l(xiāng)astPosition是不是最后一個(gè)position
//如果兩個(gè)條件都滿足則說明是真正的滑動(dòng)到了底部
if (!mIsLoading && lastChildBottom == recyclerBottom && lastPosition == recyclerView.getLayoutManager().getItemCount() - 1
&& newState == SCROLL_STATE_IDLE) {
mIsLoading = true;
post(new Runnable() {
@Override
public void run() {
if (mOnLoadingListener != null) {
mOnLoadingListener.onLoading();
}
}
});
}
}
};
//找到數(shù)組中的最大值
private int findMax(int[] lastPositions) {
int max = lastPositions[0];
for (int value : lastPositions) {
if (value > max) {
max = value;
}
}
return max;
}
private OnLoadingListener mOnLoadingListener;
public void setOnLoadingListener(OnLoadingListener onLoadingListener) {
mOnLoadingListener = onLoadingListener;
}
public interface OnLoadingListener {
void onLoading();
}
}
LoadingAdapter.java ----具有加載更多布局的adapter
/**
* <p> </p>
* Created by 行走的老者 on 2017/11/13 0013.
*/
public abstract class LoadingAdapter<B> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int FOOTER = 10000;
private static final int NORMAL = 10001;
public static final int STATUS_LOADING = 10;
public static final int STATUS_LOADED = 11;
// public static final int STATUS_LOADED = 11;
@IntDef({STATUS_LOADING, STATUS_LOADED})
public @interface Status {
}
private int mStatus = STATUS_LOADED;
private List<B> mDataList;
public void setDataList(List<B> dataList) {
mDataList = dataList;
notifyDataSetChanged();
}
public void setStatus(@Status int status) {
mStatus = status;
notifyDataSetChanged();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == FOOTER) {
return new LoadingViewHolder(LayoutInflater.from(
parent.getContext()).inflate(R.layout.loading_more_layout, parent, false));
} else
return onCreateHolder(parent, viewType);
}
protected abstract RecyclerView.ViewHolder onCreateHolder(ViewGroup parent, int viewType);
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof LoadingViewHolder) return;
onBindHolder(holder, position);
}
protected abstract void onBindHolder(RecyclerView.ViewHolder holder, int position);
@Override
public int getItemViewType(int position) {
if (position == getItemCount() - 1 && mStatus == STATUS_LOADING) {
return FOOTER;
}
return NORMAL;
}
@Override
public int getItemCount() {
return mDataList == null ? 0 : mDataList.size() + (mStatus == STATUS_LOADING ? 1 : 0);
}
//解決GridLayoutManager 占用問題
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
if (manager instanceof GridLayoutManager) {
final GridLayoutManager gridManager = ((GridLayoutManager) manager);
gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return isFooter(position) ? gridManager.getSpanCount() : 1;
}
});
}
}
private boolean isFooter(int position) {
return mStatus == STATUS_LOADING && position == getItemCount();
}
//處理StaggeredGridLayoutManager 占用問題
@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
super.onViewAttachedToWindow(holder);
if (isStaggeredGridLayout(holder)) {
handleLayoutIfStaggeredGridLayout(holder, holder.getLayoutPosition());
}
}
private boolean isStaggeredGridLayout(RecyclerView.ViewHolder holder) {
ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
return layoutParams != null && layoutParams instanceof StaggeredGridLayoutManager.LayoutParams;
}
private void handleLayoutIfStaggeredGridLayout(RecyclerView.ViewHolder holder, int position) {
if (/*isHeader(position) ||*/ isFooter(position)) {
StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
p.setFullSpan(true);
}
}
public static class LoadingViewHolder extends RecyclerView.ViewHolder {
public LoadingViewHolder(View itemView) {
super(itemView);
}
}
public static class NormalViewHolder extends RecyclerView.ViewHolder {
public NormalViewHolder(View itemView) {
super(itemView);
}
}
}