Recyclerview
自带滚动监听器,它有以下方法。
void onScrollStateChanged(RecyclerView recyclerView, int newState)
当RecyclerView的滚动状态发生变化时调用回调方法。
void onScrolled(RecyclerView recyclerView, int dx, int dy)
当RecyclerView被滚动时调用回调方法。
有什么方法可以在滚动到列表结束时触发加载器加载更多数据?
我已经实现了这个方法。
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
GenerItem generItem=generItems.get(i);
Log.d("TAG","position "+i);
if(i==generItems.size()-1)
((GenerSearchActivity)mContext).onScroll(i);
viewHolder.bindValues(generItem);
}
这里 onScroll()
活动中,将触发加载器加载更多的数据。最好的方法是什么,请建议。
这是一个滚动监听器,它实现了加载更多和快速返回模式。
public abstract class HidingScrollListener extends RecyclerView.OnScrollListener {
private static final float HIDE_THRESHOLD = 10;
private static final float SHOW_THRESHOLD = 70;
private int mToolbarOffset = 0;
private boolean mControlsVisible = true;
private int mToolbarHeight;
private int mTotalScrolledDistance;
private int previousTotal = 0;
private boolean loading = true;
private int visibleThreshold = 4;
int firstVisibleItem, visibleItemCount, totalItemCount;
private LinearLayoutManager layoutManager;
public HidingScrollListener(Context context, LinearLayoutManager layoutManager) {
mToolbarHeight = Tools.getFooterHeight(context);
this.layoutManager = layoutManager;
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
if (mTotalScrolledDistance < mToolbarHeight) {
setVisible();
}
else {
if (mControlsVisible) {
if (mToolbarOffset > HIDE_THRESHOLD) {
setInvisible();
}
else {
setVisible();
}
}
else {
if ((mToolbarHeight - mToolbarOffset) > SHOW_THRESHOLD) {
setVisible();
}
else {
setInvisible();
}
}
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
clipToolbarOffset();
onMoved(mToolbarOffset);
if ((mToolbarOffset < mToolbarHeight && dy > 0) || (mToolbarOffset > 0 && dy < 0)) {
mToolbarOffset += dy;
}
if (mTotalScrolledDistance < 0) {
mTotalScrolledDistance = 0;
}
else {
mTotalScrolledDistance += dy;
}
// for load more
visibleItemCount = recyclerView.getChildCount();
totalItemCount = layoutManager.getItemCount();
firstVisibleItem = layoutManager.findFirstVisibleItemPosition();
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
// End has been reached
// Do something
loading = true;
onLoadMore();
}
}
private void clipToolbarOffset() {
if (mToolbarOffset > mToolbarHeight) {
mToolbarOffset = mToolbarHeight;
}
else if (mToolbarOffset < 0) {
mToolbarOffset = 0;
}
}
private void setVisible() {
if (mToolbarOffset > 0) {
onShow();
mToolbarOffset = 0;
}
mControlsVisible = true;
}
private void setInvisible() {
if (mToolbarOffset < mToolbarHeight) {
onHide();
mToolbarOffset = mToolbarHeight;
}
mControlsVisible = false;
}
public abstract void onMoved(int distance);
public abstract void onShow();
public abstract void onHide();
public abstract void onLoadMore();
}
它的实现过程如下。
HidingScrollListener scrollListener = new HidingScrollListener(activity, manager) {
@Override
public void onMoved(int distance) {
}
@Override
public void onShow() {
}
@Override
public void onHide() {
}
@Override
public void onLoadMore() {
// you can do your pagination here.
}
};
mRecyclerView.addOnScrollListener(scrollListener);
基本上有3个步骤。
但首先,我们需要一个回调,作为RecyclerView.Adapter和Activity之间的桥梁。
public interface PaginationCallBack{
public void oadNextPage();
}
在您的活动中实现这个回调
class YourActivity extends AppCompatActivity implements PaginationCallBack{
int pageNum = 1;
@Override
public void loadNextPage(){
// Your implementation
}
}
在RecyclerView.Adapter中初始化回调。
class YourAdapter extends RecyclerView.Adapter{
private PaginationCallBack paginationCallBack;
public YourAdapter(PaginationCallBack paginationCallBack) {
this.paginationCallBack = paginationCallBack;
}
}
第一步增加一个条件 onBindViewHolder
方法,并用Callback通知。
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewholder, int position) {
if(position+1==images.size()){
paginationCallBack.loadNextPage(); // Callback
}
}
第二步: 调用 "下一页 "方法
getImages(++pageNum)/你的REST方法中的页码
@Override
public void loadNextPage(){
getImages(++pageNumber) // REST call with next Page
}
第三步 将结果添加到旧的列表中,并通知datasetChanged。
public void getImages(int pageNum){
List<Images> newResults = //RESTCALL
imageList.addAll(newResults);
adapter.updateDataSet(imageList)
}
updateDataSet(imageList)
方法?在RecyclerView.Adapter里面写这个方法。
public void updateDataSet(List<GalleryMedia> newImages){
if(newImages!=null){
images = newImages;
}
notifyDataSetChanged();
}