Reputation: 480
I use RecyclerView and implement autoload items when scrolling down. But i have litle problem. When server return only one item, "onScrolled event not called for loading next data. In my case item contain data for loading next datasets. Help me please. Thx.
P.S: Sorry for my English.
mNewsList.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int totalItem = mLayoutManager.getItemCount();
int lastVisibleItem = mLayoutManager.findLastVisibleItemPosition();
if (!mNewsListModel.isWorking() && lastVisibleItem == totalItem - 1 && !mNewsRecyclerAdapter.hasErrorFooter()) {
mNewsListModel.getNewsListByDate(mNewsCategory, mNewsListModel.getLastResponse().getNewsNextDate());
}
}
});
Upvotes: 1
Views: 602
Reputation: 56
I use another solution for autoload items. Add new item to adapter with another ViewType (e.g. common items has ViewType = 0 and loader item has ViewType = 1). When recyclerView call onBindViewHolder with viewType = 1 we need to start loading data. After load and put loaded items we need to remove loading item and put it again to end of list.
Adapter should be like this:
public class DemoAdapter extends RecyclerView.Adapter<DemoAdapter.ViewHolder> {
public static class ItemWrapper {
private int type;
private String name;
public ItemWrapper(int type) {
this.type = type;
}
public ItemWrapper(int type, String name) {
this.type = type;
this.name = name;
}
public int getType() {
return type;
}
public String getName() {
return name;
}
public static int getLoaderPosition(ArrayList<ItemWrapper> itemWrappers) {
for (int i = 0; i < itemWrappers.size(); i++) {
if (itemWrappers.get(i).getType() == TYPE_LOADER) {
return i;
}
}
return -1;
}
}
public static final int TYPE_ITEM = 0;
public static final int TYPE_LOADER = 1;
private boolean loadingInProgress = false;
private ArrayList<ItemWrapper> items;
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView text_title;
public ViewHolder(View v, int type) {
super(v);
if (type == TYPE_ITEM) {
text_title = (TextView) v.findViewById(R.id.text_title);
}
}
}
public DemoAdapter() {
items = new ArrayList<>();
items.add(new ItemWrapper(TYPE_ITEM, "one"));
items.add(new ItemWrapper(TYPE_ITEM, "two"));
items.add(new ItemWrapper(TYPE_ITEM, "three"));
items.add(new ItemWrapper(TYPE_LOADER));
}
public int getItemCount() {
return items.size();
}
public ItemWrapper getItem(int position) {
return items.get(position);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_ITEM) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.elem_demo, parent, false);
ViewHolder vh = new ViewHolder(v, viewType);
return vh;
}
else if (viewType == TYPE_LOADER) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.elem_loader, parent, false);
ViewHolder vh = new ViewHolder(v, viewType);
return vh;
}
return null;
}
private void startLoadData() {
if (!loadingInProgress) {
loadingInProgress = true;
// load your data here
// then update list
onLoadSuccess(loadedItems);
}
}
private void onLoadSuccess(final ArrayList<ItemWrapper> loadedItems) {
try {
final int loaderPosition = ItemWrapper.getLoaderPosition(items);
items.remove(loaderPosition);
notifyItemRemoved(loaderPosition);
items.addAll(loadedItems);
items.add(new ItemWrapper(TYPE_LOADER));
notifyItemRangeInserted(loaderPosition, loadedItems.size());
}
catch (Exception e) {}
}
@Override
public int getItemViewType(int position) {
return getItem(position).getType();
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
int type = getItemViewType(position);
if (type == TYPE_ITEM) {
holder.text_title.setText(getItem(position).getName());
}
else if (type == TYPE_LOADER) {
startLoadData();
}
}
}
Upvotes: 1