RecylerView's onScrollChanged() does not detects bottom of screen in Android - android

I am implementing a functionality in which I need to hit API again to fetch data while the list reaches to its end. I have used onScrollListener of RecyclerView to detect whether it reaches to end or not but code only runs first time when I opens the screen but it not work when it reaches to screens end.
How can I check when list reaches to its end.
Fragment Code:
#SuppressLint("RestrictedApi")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_home, container, false);
initScrollListener();
}
private void initScrollListener() {
list.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(#NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
Toast.makeText(getActivity(), "Loading", Toast.LENGTH_SHORT).show();
if (!isLoading) {
if (linearLayoutManager != null && linearLayoutManager.findLastCompletelyVisibleItemPosition() == rowsArrayList.size() - 1) {
//bottom of list!
loadMore();
isLoading = true;
}
}
}
});
}
private void loadMore() {
rowsArrayList.add(null);
postListAdapter.notifyItemInserted(rowsArrayList.size() - 1);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
rowsArrayList.remove(rowsArrayList.size() - 1);
int scrollPosition = rowsArrayList.size();
postListAdapter.notifyItemRemoved(scrollPosition);
int currentSize = scrollPosition;
int nextLimit = currentSize + 10;
while (currentSize - 1 < nextLimit) {
rowsArrayList.add("Item " + currentSize);
currentSize++;
}
postListAdapter.notifyDataSetChanged();
isLoading = false;
}
}, 2000);
}
Adapter Code:
public class PostListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
Context context;
List<StoriesDatum> storiesDatumList;
StoriesDatum storiesDatum;
FragmentHome fragmentHome;
int qty;
View itemView;
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1;
public PostListAdapter(Context context, List<StoriesDatum> storiesDatumList, FragmentHome fragmentHome) {
this.context = context;
this.storiesDatumList = storiesDatumList;
this.fragmentHome = fragmentHome;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_ITEM) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post, parent, false);
return new MyViewHolder(view);
} else {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_loading, parent, false);
return new LoadingViewHolder(view);
}
}
#Override
public void onBindViewHolder(#NonNull final RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof MyViewHolder) {
populateItemRows((MyViewHolder) holder, position);
} else if (holder instanceof LoadingViewHolder) {
showLoadingView((LoadingViewHolder) holder, position);
}
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return storiesDatumList.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM;
}
#Override
public int getItemCount() {
return storiesDatumList.size();
}
private class LoadingViewHolder extends RecyclerView.ViewHolder {
ProgressBar progressBar;
public LoadingViewHolder(#NonNull View itemView) {
super(itemView);
progressBar = itemView.findViewById(R.id.progressBar);
}
}
private void showLoadingView(LoadingViewHolder viewHolder, int position) {
//ProgressBar would be displayed
}
private void populateItemRows(MyViewHolder myViewHolder, final int position) {
String item = storiesDatumList.get(position).toString();
storiesDatum = storiesDatumList.get(position);
myViewHolder.txtCommunityName.setText(storiesDatum.getComTitle());
myViewHolder.txtPostTitle.setText(storiesDatum.getTitle());
String comm_photo = String.valueOf(storiesDatum.getComImage());
if (comm_photo == null || comm_photo.equals("null") || comm_photo.equals("")) {
myViewHolder.ivImage.setImageResource(R.mipmap.top_communities_circle);
} else {
if (comm_photo.startsWith("https://") || comm_photo.startsWith("http://")) {
long interval = 5000 * 1000;
Glide.with(context).load(comm_photo)
.into(myViewHolder.ivImage);
} else {
Glide.with(context).load(Constants.image_url + comm_photo)
.into(myViewHolder.ivImage);
}
}
myViewHolder.txtNamePosted.setText("Posted by " + storiesDatum.getUsername());
String created_date = storiesDatum.getCreatedAt();
//call date
String corecDate = fragmentHome.createDate(created_date);
myViewHolder.txtTime.setText(corecDate);
myViewHolder.txtCommentCount.setText(storiesDatum.getCommentsCount() + " Comments");
myViewHolder.txtLikeCount.setText(storiesDatum.getStoryemojiCount() + " Reactions");
/*change code for adapter*/
myViewHolder.tvPost.setText(storiesDatum.getSnapshots());
if (storiesDatum.getStoryBody() != null) {
myViewHolder.tvBody.setVisibility(View.VISIBLE);
myViewHolder.tvBody.setText(storiesDatum.getStoryBody());
} else {
myViewHolder.tvBody.setVisibility(View.GONE);
}
if (storiesDatum.getStoryType() == 2) {
myViewHolder.videoPost.setVisibility(View.GONE);
myViewHolder.youTubePlayerView.setVisibility(View.GONE);
if (storiesDatum.getStoryUpload() == null && (storiesDatum.getStoryUrl() != null)) {
myViewHolder.ivImageViaLink.setVisibility(View.VISIBLE);
myViewHolder.ivPostImage.setVisibility(View.GONE);
String story_url = storiesDatum.getStoryUrl().toString();
Log.e("TAG", "onResponse:story1 " + story_url);
if (story_url.startsWith("https://") || story_url.startsWith("http://")) {
Glide.with(context).load(story_url)
.into(myViewHolder.ivImageViaLink);
} else {
Glide.with(context).load(story_url)
// .placeholder(R.mipmap.top_communities_circle)
//.error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivImageViaLink);
}
} else if (storiesDatum.getStoryUrl() == null && (storiesDatum.getStoryUpload() != null)) {
myViewHolder.ivImageViaLink.setVisibility(View.GONE);
myViewHolder.ivPostImage.setVisibility(View.VISIBLE);
String story_url = storiesDatum.getStoryUpload().toString();
Log.e("TAG", "onResponse:story2 " + story_url);
if (story_url.startsWith("https://") || story_url.startsWith("http://")) {
Glide.with(context).load(story_url)
// .placeholder(R.mipmap.top_communities_circle)
//.error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivPostImage);
} else {
Glide.with(context).load(Constants.image_url + story_url)
// .placeholder(R.mipmap.top_communities_circle)
// .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivPostImage);
}
} else {
myViewHolder.ivImageViaLink.setVisibility(View.VISIBLE);
myViewHolder.ivPostImage.setVisibility(View.VISIBLE);
String story_upload = storiesDatum.getStoryUpload().toString();
Log.e("TAG", "onResponse:story3 " + story_upload);
if (story_upload.startsWith("https://") || story_upload.startsWith("http://")) {
Glide.with(context).load(story_upload)
//.placeholder(R.mipmap.top_communities_circle)
//.error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivPostImage);
} else {
Glide.with(context).load(Constants.image_url + story_upload)
// .placeholder(R.mipmap.top_communities_circle)
// .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivPostImage);
}
String story_url = storiesDatum.getStoryUrl().toString();
Log.e("TAG", "onResponse:story4 " + story_url);
if (story_url.startsWith("https://") || story_url.startsWith("http://")) {
Glide.with(context).load(story_url)
//.placeholder(R.mipmap.top_communities_circle)
// .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivImageViaLink);
} else {
Glide.with(context).load(story_url)
// .placeholder(R.mipmap.top_communities_circle)
// .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivImageViaLink);
}
}
} else if (storiesDatum.getStoryType() == 3) {
myViewHolder.videoPost.setVisibility(View.GONE);
myViewHolder.youTubePlayerView.setVisibility(View.GONE);
if (storiesDatum.getStoryUpload() == null && (storiesDatum.getStoryUrl() != null)) {
myViewHolder.ivImageViaLink.setVisibility(View.VISIBLE);
myViewHolder.btn_play.setVisibility(View.VISIBLE);
myViewHolder.ivPostImage.setVisibility(View.GONE);
String story_url1 = storiesDatum.getStoryUrl().toString();
String[] cutLink = story_url1.split("frameborder");
String[] cutLink1 = cutLink[0].split("embed/");
String link = cutLink1[1];
final String played_link = link.split("\"")[0];
String story_url = "https://img.youtube.com/vi/" + played_link + "/0.jpg";
Log.e("TAG", "onResponse:story1 " + story_url);
if (story_url.startsWith("https://") || story_url.startsWith("http://")) {
Glide.with(context).load(story_url)
// .placeholder(R.mipmap.top_communities_circle)
// .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivImageViaLink);
} else {
Glide.with(context).load(story_url)
// .placeholder(R.mipmap.top_communities_circle)
// .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivImageViaLink);
}
} else if (storiesDatum.getStoryUrl() == null && (storiesDatum.getStoryUpload() != null)) {
myViewHolder.ivImageViaLink.setVisibility(View.GONE);
myViewHolder.ivPostImage.setVisibility(View.VISIBLE);
myViewHolder.play.setVisibility(View.VISIBLE);
String story_url = storiesDatum.getStoryUpload().toString();
Log.e("TAG", "onResponse:story2 " + story_url);
} else {
myViewHolder.ivImageViaLink.setVisibility(View.VISIBLE);
myViewHolder.ivPostImage.setVisibility(View.VISIBLE);
myViewHolder.btn_play.setVisibility(View.VISIBLE);
myViewHolder.play.setVisibility(View.VISIBLE);
String story_upload = storiesDatum.getStoryUpload().toString();
Uri videoURI;
videoURI = Uri.parse(Constants.image_url + story_upload);
Log.e("TAG", "onResponse:story3 " + videoURI);
String story_url1 = storiesDatum.getStoryUrl().toString();
String[] cutLink = story_url1.split("frameborder");
String[] cutLink1 = cutLink[0].split("embed/");
String link = cutLink1[1];
final String played_link = link.split("\"")[0];
String story_url = "https://img.youtube.com/vi/" + played_link + "/0.jpg";
Log.e("TAG", "onResponse:story4 " + story_url);
if (story_url.startsWith("https://") || story_url.startsWith("http://")) {
Glide.with(context).load(story_url)
// .placeholder(R.mipmap.top_communities_circle)
// .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivImageViaLink);
} else {
Glide.with(context).load(story_url)
// .placeholder(R.mipmap.top_communities_circle)
// .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivImageViaLink);
}
}
// viewHolder.tvItem.setText(item);
myViewHolder.txtCommunityName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
storiesDatum = storiesDatumList.get(position);
fragmentHome.sendToCommunityPage(storiesDatum.getComTitle(), storiesDatum.getCommunityId(), storiesDatum.getComImage());
}
});
myViewHolder.txtNamePosted.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
storiesDatum = storiesDatumList.get(position);
fragmentHome.sendToUserProfile(storiesDatum.getUserId(), storiesDatum.getUsername(), storiesDatum.getProfile_pic());
}
});
myViewHolder.ivAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
storiesDatum = storiesDatumList.get(position);
fragmentHome.addCommunity(storiesDatum.getCommunityId());
}
});
Log.e("tag", "jpined_favourite" + storiesDatum.getJoined() + storiesDatum.getFav());
if (storiesDatum.getJoined() == 0) {
myViewHolder.ivAdd.setVisibility(View.VISIBLE);
} else {
myViewHolder.ivAdd.setVisibility(View.GONE);
}
if (storiesDatum.getFav() == 1) {
myViewHolder.ivFav.setImageResource(R.mipmap.mark_as_favorite_filled);
} else {
myViewHolder.ivFav.setImageResource(R.mipmap.mark_favorite);
}
myViewHolder.txtComment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fragmentHome.openCommentbox();
}
});
myViewHolder.ivFav.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
storiesDatum = storiesDatumList.get(position);
if (storiesDatum.getFav() == 0) {
fragmentHome.addFavt(storiesDatum.getCommunityId().toString(), "markfav");
} else {
fragmentHome.addFavt(storiesDatum.getCommunityId().toString(), "unmarkfav");
}
}
});
myViewHolder.relativeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//fragmentHome.sendToSinglePost();
StoriesDatum storiesDatum1 = storiesDatumList.get(position);
fragmentHome.sendToSinglePost(storiesDatum1.getId().toString());
}
});
myViewHolder.relativeShare.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
StoriesDatum storiesDatum1 = storiesDatumList.get(position);
fragmentHome.sharepost(storiesDatum1.getSlugid(), storiesDatum1.getSlug());
}
});
}
}
public class MyViewHolder extends RecyclerView.ViewHolder {
}

Use this method
RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) //check for scroll down
{
if (!mNoMoreLoad) {
if ((mLayoutManager.getChildCount() +
mLayoutManager.findFirstVisibleItemPosition()) >= mLayoutManager.getItemCount()) {
mPage++;
mNoMoreLoad = true;
loadMore(mPage);
}
}
}
}
private void loadMore(int mPage) {
if (Utils.getInstance().isNetworkAvailable(getActivity())) {
hit api with page number
}
}
after getting response check the size of new data with your data limit
if (response.getData().size() < Constants.DATA_LIMIT) {
mNoMoreLoad = true;
} else {
mNoMoreLoad = false;
}

You can do this in the following ways:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged( RecyclerView recyclerView, int newState) {
if(!recyclerView.canScrollVertically(1))
Log.e(TAG,TAG+"<<end-333->>"); //Here is one way
super.onScrollStateChanged(recyclerView, newState);
}
#Override
public void onScrolled( RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
Log.e(TAG,TAG+"<<end-->>"+linearLayoutManager.findLastVisibleItemPosition());
if(linearLayoutManager.findLastVisibleItemPosition() == linearLayoutManager.getItemCount()-1)
{
Log.e(TAG,TAG+"<<end-22->>"+linearLayoutManager.findLastVisibleItemPosition()); //Here is another way
}
}
});
}

Related

Getting a RecyclerView to reload items

I am currently working on an app, that finds all MP3s on a users phone and then puts them into a list. This works very fine and is very quick, even with many songs. Now I populate a new list with an object for each item of the list to then display it inside my recyclerview. The problem is, that I have 700+ songs on my phone and this blocks the UI thread quite some time.
Now, I want to use the recyclerview to not load all items from the list into the objects all at once but rather only when they are about to be displayed - but I have NO clue over how to do this. Right now, all objects are build and then displayed in a very long scrollview from the recyclerview after the UI thread has been blocked for a good 30 seconds. Can please anyone help me? Here is my code:
namespace Media_Player
{
[Activity(Label = "Media_Player", MainLauncher = true)]
public class MainActivity : Activity
{
static public MediaPlayer mediaPlayer;
List<MP3object> mp3;
MediaMetadataRetriever reader;
public static Button btn_StartOrPause, btn_Stop;
public static TextView txt_CurrentSong;
public static bool stopIsActive = false, firstStart = true;
public static Android.Net.Uri CurrentActiveSongUri;
RecyclerView mRecyclerView;
RecyclerView.LayoutManager mLayoutManager;
PhotoAlbumAdapter mAdapter;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.test);
reader = new MediaMetadataRetriever();
PopulateMP3List(ReturnPlayableMp3(true));
mediaPlayer = new MediaPlayer();
InitRecView();
}
private void InitRecView()
{
// Instantiate the adapter and pass in its data source:
mAdapter = new PhotoAlbumAdapter(mp3);
// Get our RecyclerView layout:
mRecyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);
// Plug the adapter into the RecyclerView:
mRecyclerView.SetAdapter(mAdapter);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.SetLayoutManager(mLayoutManager);
}
private void PopulateMP3List(List<string> content)
{
mp3 = new List<MP3object>();
foreach (string obj in content)
{
WriteMetaDataToFileList(obj);
}
}
void WriteMetaDataToFileList(string obj)
{
reader.SetDataSource(obj);
//Write Mp3 as object to global list
MP3object ob = new MP3object();
{
if(reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyTitle) != "" && reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyTitle) != null)
{
ob.SongName = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyTitle);
}
else
{
ob.SongName = Resources.GetString(Resource.String.Unknown);
}
if (reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyArtist) != "" && reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyArtist) != null)
{
ob.ArtistName = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyArtist);
}
else
{
ob.ArtistName = Resources.GetString(Resource.String.Unknown);
}
if (reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyAlbum) != "" && reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyAlbum) != null)
{
ob.AlbumName = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyAlbum);
}
else
{
ob.AlbumName = Resources.GetString(Resource.String.Unknown);
}
if (reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear) != "" && reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear) != null)
{
ob.Year = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear);
}
else
{
ob.Year = Resources.GetString(Resource.String.Unknown);
}
if (reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear) != "" && reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear) != null)
{
ob.Year = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyYear);
}
else
{
ob.Year = Resources.GetString(Resource.String.Unknown);
}
ob.Mp3Uri = obj; // can never be unknown!
ob.DurationInSec = int.Parse(reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyDuration)) / 1000; // can never be unknown, div by 1000 to get sec not millis
}
mp3.Add(ob);
}
public List<string> ReturnPlayableMp3(bool sdCard)
{
List<string> res = new List<string>();
string phyle;
string path1 = null;
if(sdCard) // get mp3 from SD card
{
string baseFolderPath = "";
try
{
bool getSDPath = true;
Context context = Application.Context;
Java.IO.File[] dirs = context.GetExternalFilesDirs(null);
foreach (Java.IO.File folder in dirs)
{
bool IsRemovable = Android.OS.Environment.InvokeIsExternalStorageRemovable(folder);
bool IsEmulated = Android.OS.Environment.InvokeIsExternalStorageEmulated(folder);
if (getSDPath ? IsRemovable && !IsEmulated : !IsRemovable && IsEmulated)
baseFolderPath = folder.Path;
}
}
catch (Exception ex)
{
Console.WriteLine("GetBaseFolderPath caused the following exception: {0}", ex);
}
string xy = baseFolderPath.Remove(18); // This is result after this, but this hard coded solution could be a problem on different phones.: "/storage/05B6-2226/Android/data/Media_Player.Media_Player/files"
path1 = xy;
// path to SD card and MUSIC "/storage/05B6-2226/"
}
else // get Mp3 from internal storage
{
path1 = Android.OS.Environment.ExternalStorageDirectory.ToString();
}
var mp3Files = Directory.EnumerateFiles(path1, "*.mp3", SearchOption.AllDirectories);
foreach (string currentFile in mp3Files)
{
phyle = currentFile;
res.Add(phyle);
}
return res;
}
}
public class PhotoViewHolder : RecyclerView.ViewHolder
{
public ImageView Image { get; private set; }
public TextView Caption { get; private set; }
public PhotoViewHolder(View itemView) : base(itemView)
{
// Locate and cache view references:
Image = itemView.FindViewById<ImageView>(Resource.Id.imageView);
Caption = itemView.FindViewById<TextView>(Resource.Id.textView);
}
}
public class PhotoAlbumAdapter : RecyclerView.Adapter
{
public List<MP3object> mp3;
public PhotoAlbumAdapter(List<MP3object> mp3)
{
this.mp3 = mp3;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).
Inflate(Resource.Layout.lay, parent, false);
PhotoViewHolder vh = new PhotoViewHolder(itemView);
return vh;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
PhotoViewHolder vh = holder as PhotoViewHolder;
vh.Caption.Text = mp3[position].SongName;
}
public override int ItemCount
{
get { return mp3.Count(); }
}
}
}
So getting the list of strings with the locations of the Mp3 works very quickly, but then "WriteMetaDataToFileList(obj)" kicks in, comming from "PopulateMP3List(List content)" and this is what takes so long. What I think I need is for the recyclerview to only build the first 20 objects, and when the user starts scrolling, builds the next 20 objects and attaches them to list for them to also be scrolled. Please help me out here :)
Here is an abstract class:
public abstract class PaginationScrollListener extends RecyclerView.OnScrollListener {
private LinearLayoutManager linearLayoutManager;
protected PaginationScrollListener(LinearLayoutManager linearLayoutManager) {
this.linearLayoutManager = linearLayoutManager;
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = linearLayoutManager.getChildCount();
int totalItemCount = linearLayoutManager.getItemCount();
int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
if (!isLoading() && !isLastPage()) {
if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount && firstVisibleItemPosition >= 0) {
loadMoreItems();
}
}
}
protected abstract void loadMoreItems();
public abstract boolean isLastPage();
public abstract boolean isLoading();
}
and In your adapter you must follow this pattern:
public class ConsultancyAdapter extends RecyclerView.Adapter<ConsultancyAdapter.ConsultancyVH> {
private static final int ITEM = 0;
private static final int LOADING = 1;
private boolean isLoadingAdded = false;
public ConsultancyAdapter(List<Consultancy> consultancies, ConsultancyAdapterListener listener) {
}
#NonNull
#Override
public ConsultancyVH onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case ITEM:
viewHolder = getViewHolder(parent, layoutInflater);
break;
case LOADING:
View v2 = layoutInflater.inflate(R.layout.item_progress, parent, false);
viewHolder = new ConsultancyVH(v2);
break;
}
return (ConsultancyVH) viewHolder;
}
#NonNull
private RecyclerView.ViewHolder getViewHolder(ViewGroup parent, LayoutInflater inflater) {
RecyclerView.ViewHolder viewHolder;
View v1 = inflater.inflate(R.layout.item_consultancy, parent, false);
viewHolder = new ConsultancyVH(v1);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ConsultancyVH holder, int position) {
Consultancy consultancy = consultancies.get(position);
switch (getItemViewType(position)) {
case ITEM:
ConsultancyVH mySingeCounseller = holder;
holder.title.setText(consultancy.getTitle()); // set cardTitle
holder.fieldArea.setText(consultancy.getField_filedoctorskills());
break;
case LOADING:
break;
}
}
#Override
public int getItemCount() {
return consultancies.size();
}
#Override
public int getItemViewType(int position) {
return (position == consultancies.size() - 1 && isLoadingAdded) ? LOADING : ITEM;
}
public void add(Consultancy mc) {
consultancies.add(mc);
notifyItemInserted(consultancies.size() - 1);
}
public void addAll(List<Consultancy> mcList) {
for (Consultancy mc : mcList) {
add(mc);
}
}
public void remove(Consultancy city) {
int position = consultancies.indexOf(city);
if (position > -1) {
consultancies.remove(position);
notifyItemRemoved(position);
}
}
public Consultancy getItem(int position) {
return consultancies.get(position);
}
public void clear() {
isLoadingAdded = false;
while (getItemCount() > 0) {
remove(getItem(0));
}
}
public boolean isEmpty() {
return getItemCount() == 0;
}
public void addLoadingFooter() {
isLoadingAdded = true;
add(new Consultancy());
}
public void removeLoadingFooter() {
isLoadingAdded = false;
int position = consultancies.size() - 1;
Consultancy item = getItem(position);
if (item != null) {
consultancies.remove(position);
notifyItemRemoved(position);
}
}
public interface ConsultancyAdapterListener {
void onCaseClicked(int position, String nid, String fieldArea, String title);
}
protected class ConsultancyVH extends RecyclerView.ViewHolder {
private TextView title, fieldArea;
private CircleImageView iconProfile;
private MaterialRippleLayout caseButtonRipple;
public ConsultancyVH(View itemView) {
super(itemView);
caseButtonRipple = itemView.findViewById(R.id.case_button_ripple);
this.title = itemView.findViewById(R.id.docName);
this.fieldArea = itemView.findViewById(R.id.fieldArea);
this.iconProfile = itemView.findViewById(R.id.icon_profile);
}
}
}
and in your activity:
private void setScrollListener() {
recyclerView.addOnScrollListener(new PaginationScrollListener(linearLayoutManager) {
#Override
protected void loadMoreItems() {
isLoading = true;
currentPage += 1;
loadNextPage();
}
#Override
public boolean isLastPage() {
return isLastPage;
}
#Override
public boolean isLoading() {
return isLoading;
}
});
loadFirstPage();
}
and in my loadFirstPage i talk to a API and you need some your code:
private void loadFirstPage() {
CallData().enqueue(new DefaultRetrofitCallback<List<Consultancy>>() {
#Override
protected void onFailure(Throwable t) {
super.onFailure(t);
}
#Override
protected void onSuccess(List<Consultancy> response) {
swipeRefreshLayout.setRefreshing(false);
dataList = response;
adapter.addAll(dataList);
recyclerView.setAdapter(adapter);
if (!checkLast(response)) adapter.addLoadingFooter();
else isLastPage = true;
}
#Override
protected void onOtherStatus(Response<List<Consultancy>> response) {
super.onOtherStatus(response);
}
#Override
protected void always() {
super.always();
}
});
}
and loadNextPage:
private void loadNextPage() {
CallData().enqueue(new DefaultRetrofitCallback<List<Consultancy>>() {
#Override
protected void onFailure(Throwable t) {
super.onFailure(t);
}
#Override
protected void onSuccess(List<Consultancy> response) {
swipeRefreshLayout.setRefreshing(false);
adapter.removeLoadingFooter();
isLoading = false;
swipeRefreshLayout.setRefreshing(false);
adapter.addAll(response);
if (!checkLast(response)) adapter.addLoadingFooter();
else isLastPage = true;
}
#Override
protected void onOtherStatus(Response<List<Consultancy>> response) {
super.onOtherStatus(response);
}
#Override
protected void always() {
super.always();
}
});
}

Increment Page Index for Paginated Recyclerview

I have implemented pagination in my app but I am having trouble with incrementing the page index. I am getting data from unsplash api and have formed the request url like below:
private String url = Constants.SEARCH_URL + "top30&page="+ PAGE_INDEX;
and this is the url used below:
https://api.unsplash.com/search/photos?client_id=api_key&order_by=latest&query=top30&page=1
In my fragment, I have a constant int like private static int PAGE_INDEX = 1; which tracks the current page and used for getting the next pages till page limit.
The first request runs fine and when scrolling towards the last item, more items are fetched. However, these items are same as from the first page index and after logging the url, I get the same as in first request like below:
https://api.unsplash.com/search/photos?client_id=api_key&order_by=latest&query=top30&page=1
I have attached my scroll listener in recyclerview like this and incremented the PAGE_INDEX but not getting the next page in url but in log cat it shows the page index as 2. Here's the listener attached:
top30RV.addOnScrollListener(new PaginationScrollListener(llm) {
#Override
protected void loadMoreItems() {
isLoading = true;
PAGE_INDEX = PAGE_INDEX + 1;
Log.d(TAG, "PIn:\t" + PAGE_INDEX);
loadNextPage();
}
#Override
protected int getTotalPageCount() {
return PAGE_COUNT;
}
#Override
public boolean isLoading() {
return isLoading;
}
#Override
public boolean isLastPage() {
return isLastPage;
}
});
and my PaginationScrollListener class code:
public abstract class PaginationScrollListener extends RecyclerView.OnScrollListener {
LinearLayoutManager llm;
public PaginationScrollListener(LinearLayoutManager llm) {
this.llm = llm;
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visisbleItemCount = recyclerView.getChildCount();
int totalItemCount = llm.getItemCount();
int firstVisibleItemPosn = llm.findFirstVisibleItemPosition();
if (!isLoading() && !isLastPage()){
if ((visisbleItemCount + firstVisibleItemPosn) >= totalItemCount && firstVisibleItemPosn > 0){
loadMoreItems();
}
}
}
protected abstract void loadMoreItems();
protected abstract int getTotalPageCount();
public abstract boolean isLoading();
public abstract boolean isLastPage();
}
in my adapter I have called the method to addLoadingFooter and it works but also the progressbar is not dismissed and removeLoadingFooter is called but doesn't work because of the page index is less than the page limit.
public class Top30Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final String TAG = Top30Adapter.class.getSimpleName();
private final Context context;
private List<UnsplashImages> itemsList;
private UnsplashImages unsplashImages;
private static final int ITEMS = 0;
private static final int PROGRESS = 1;
private boolean isLoadingAdded = false;
private boolean retryPageLoad = false;
private String errorMsg;
private PaginationAdapterCallback mCallback;
public Top30Adapter(Context context, List<UnsplashImages> itemsList) {
this.context = context;
this.itemsList = itemsList;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType){
case ITEMS:
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.wallpaper_items_layout, parent, false);
return new WallpaperItemViewHolder(view);
case PROGRESS:
View pv = LayoutInflater.from(parent.getContext()).inflate(R.layout.progress_items_layout, parent, false);
return new LoadingViewHolder(pv);
}
return null;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewholder, final int position) {
switch (getItemViewType(position)){
case ITEMS:
WallpaperItemViewHolder wallpaperItemViewHolder = (WallpaperItemViewHolder) viewholder;
unsplashImages = (UnsplashImages) itemsList.get(position);
Picasso.with(context)
.load(unsplashImages.getRegularImg())
.placeholder(R.drawable.drawer_header_trimmed)
.into(wallpaperItemViewHolder.wallpaperItemImg);
wallpaperItemViewHolder.favoriteWP_IV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Favorites favorites = new Favorites();
favorites.setFavoritesId(UUID.randomUUID().toString());
favorites.setLargeImgURL(unsplashImages.getRegularImg());
favorites.setPreviewImgURL(unsplashImages.getRegularImg());
favorites.save();
Toast.makeText(context, "Added to Favorites", Toast.LENGTH_SHORT).show();
}
});
wallpaperItemViewHolder.setWallPaper_TV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final WallpaperManager wpm = WallpaperManager.getInstance(context);
Picasso.with(context)
.load(((UnsplashImages) itemsList.get(position)).getRegularImg())
.into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
try {
wpm.setBitmap(bitmap);
Toast.makeText(context, "Your New Wallpaper Has Been Set", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
Log.d(TAG, "Bitmap Load Failed");
Toast.makeText(context, "Could Not Set Wallpaper...Choose Another", Toast.LENGTH_SHORT).show();
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Log.d(TAG, "Prep to Load Bitmap");
}
});
}
});
break;
case PROGRESS:
LoadingViewHolder loadingViewHolder = (LoadingViewHolder) viewholder;
if (retryPageLoad){
loadingViewHolder.mErrorLayout.setVisibility(View.VISIBLE);
loadingViewHolder.mProgressBar.setVisibility(View.GONE);
loadingViewHolder.mErrorTxt.setText(errorMsg != null
? errorMsg
: context.getString(R.string.error_msg_unknown));
} else {
loadingViewHolder.mErrorLayout.setVisibility(View.GONE);
loadingViewHolder.mProgressBar.setVisibility(View.VISIBLE);
}
break;
}
}
#Override
public int getItemCount() {
if (itemsList == null) {
return 0;
}
return itemsList.size();
}
#Override
public int getItemViewType(int position) {
return (position == itemsList.size() - 1 && isLoadingAdded) ? PROGRESS : ITEMS;
}
public void addImage(UnsplashImages images){
itemsList.add(images);
notifyItemInserted(itemsList.size() - 1);
}
public void addAllImages(List<UnsplashImages> list){
for (UnsplashImages images : list){
addImage(images);
}
}
public void addLoadingFooter() {
isLoadingAdded = true;
addImage(new UnsplashImages());
}
public void removeLoadingFooter(){
isLoadingAdded = false;
int position = itemsList.size() - 1;
UnsplashImages unsplashImages = getItem(position);
if (unsplashImages != null){
itemsList.remove(unsplashImages);
notifyItemRemoved(position);
}
}
private UnsplashImages getItem(int position) {
return itemsList.get(position);
}
public void showRetry(boolean show, #Nullable String errorMsg){
retryPageLoad = true;
notifyItemChanged(itemsList.size() - 1);
if (errorMsg != null){this.errorMsg = errorMsg; } else { errorMsg = "Can't Fetch Wallpapers Now..."; }
}
}
Full fragment code:
public class Top30Fragment extends Fragment {
private static final String TAG = Top30Fragment.class.getSimpleName();
private RecyclerView top30RV;
private List<UnsplashImages> itemsList = new ArrayList<>();
private Top30Adapter adapter;
private int PAGE_COUNT;
private static int PAGE_INDEX = 1;
private static int PER_PAGE = 20;
private static int CURRENT_PAGE = PAGE_INDEX;
private boolean isLoading = false;
private boolean isLastPage = false;
private String url = Constants.SEARCH_URL + "top30&page="+ PAGE_INDEX;
public Top30Fragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View vtop = inflater.inflate(R.layout.fragment_top30, container, false);
top30RV = vtop.findViewById(R.id.top30RV);
top30RV.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
top30RV.setLayoutManager(llm);
if (Utils.isNetwork(getActivity())){
fetchWallpapers();
} else {
Snackbar.make(getActivity().findViewById(android.R.id.content), "Check Connection", Snackbar.LENGTH_LONG).show();
}
adapter = new Top30Adapter(getActivity(), itemsList);
top30RV.setAdapter(adapter);
top30RV.addOnScrollListener(new PaginationScrollListener(llm) {
#Override
protected void loadMoreItems() {
isLoading = true;
PAGE_INDEX = PAGE_INDEX + 1;
Log.d(TAG, "PIn:\t" + PAGE_INDEX);
loadNextPage();
}
#Override
protected int getTotalPageCount() {
return PAGE_COUNT;
}
#Override
public boolean isLoading() {
return isLoading;
}
#Override
public boolean isLastPage() {
return isLastPage;
}
});
adapter.notifyDataSetChanged();
return vtop;
}
private void loadNextPage() {
int newIndex = PAGE_INDEX +=1;
Log.d(TAG, "Next Page:\t" + newIndex);
Log.d(TAG, "Next Page Index:\t" + newIndex);
Log.d(TAG, "Next Page URL:\t" + url);
AndroidNetworking.get(url)
.setTag("Load Next Top30")
.setPriority(Priority.HIGH)
.build()
.getAsJSONObject(new JSONObjectRequestListener() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, "Next Page Response:\t" + response.toString());
if (response != null){
isLoading = false;
adapter.removeLoadingFooter();
try {
JSONObject jsonObject = new JSONObject(response.toString());
JSONArray results = jsonObject.getJSONArray("results");
for (int p = 0; p < results.length(); p++){
JSONObject items = results.getJSONObject(p);
UnsplashImages images = new UnsplashImages();
images.setImageId(items.getString("id"));
JSONObject urls = items.getJSONObject("urls");
images.setRawImg(urls.getString("raw"));
images.setFullImg(urls.getString("full"));
images.setRegularImg(urls.getString("regular"));
images.setSmallImg(urls.getString("small"));
images.setThumbImg(urls.getString("thumb"));
itemsList.add(images);
adapter.notifyDataSetChanged();
Log.d(TAG, "New List Size:\t" + itemsList.size());
if (CURRENT_PAGE != PAGE_COUNT){
adapter.addLoadingFooter();
} else {
isLastPage = true;
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
#Override
public void onError(ANError anError) {
}
});
}
private void fetchWallpapers() {
// String url = Constants.SEARCH_URL + "top30&page="+ PAGE_INDEX + "per_page=" + PER_PAGE;
Log.d(TAG, "Top30 Unsplash URL:\t" + url);
AndroidNetworking.get(url)
.setPriority(Priority.HIGH)
.setTag("Get Seasons Wallpapers")
.build()
.getAsJSONObject(new JSONObjectRequestListener() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, "Un-Response:\t" + response.toString());
if (response != null){
try {
JSONObject jsonObject = new JSONObject(response.toString());
PAGE_COUNT = jsonObject.getInt("total_pages");
Log.d(TAG, "Page Count:\t" + PAGE_COUNT);
JSONArray results = jsonObject.getJSONArray("results");
for (int p = 0; p < results.length(); p++){
JSONObject items = results.getJSONObject(p);
UnsplashImages images = new UnsplashImages();
images.setImageId(items.getString("id"));
JSONObject urls = items.getJSONObject("urls");
images.setRawImg(urls.getString("raw"));
images.setFullImg(urls.getString("full"));
images.setRegularImg(urls.getString("regular"));
images.setSmallImg(urls.getString("small"));
images.setThumbImg(urls.getString("thumb"));
itemsList.add(images);
adapter.notifyDataSetChanged();
Log.d(TAG, "List Size:\t" + itemsList.size());
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
#Override
public void onError(ANError anError) {
}
});
}
Is there another way to construct the request url to increment the page index? Thanks.

RecycleView repeat action on one recycleview card on other

I am developing one quiz android application in which questions and their respective options and answer will be fetched from server and added to recycle view.
I have done coding of same and it is working except one problem that when i choose any option i turn its background green if it is right or i turn it to red if it is wrong but when i do same for any question same action is been transformed on other questions option in recycle view.
As i click on Option A
6th question from previous solved question have option A automatically selected
I am posting my Adapter and Fragment code for same.
Adapter code:-
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(context);
Log.e("I : ", "Creating " );
switch (viewType) {
case QUESTION:
View viewQuestion = inflater.inflate(R.layout.question_card, parent, false);
viewHolder = new QuestionFeed(viewQuestion);
break;
case LOADING:
View viewLoading = inflater.inflate(R.layout.item_progress, parent, false);
viewHolder = new LoadingVH(viewLoading);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final PostRead result = postResults.get(position);
String catname = null;
try {
catname = dataBaseHelper.getCatName(result.getCat());
} catch (SQLException e) {
e.printStackTrace();
}
Log.e("Position: ", "" + position);
switch (getItemViewType(position)) {
case QUESTION:
final QuestionFeed textFeed = (QuestionFeed) holder;
textFeed.question.setText(result.getQuestion());
textFeed.optionA.setText(result.getA());
textFeed.optionB.setText(result.getB());
textFeed.optionC.setText(result.getC());
textFeed.optionD.setText(result.getD());
textFeed.answerView.setText(catname);
textFeed.time.setText("" + TimeAgo.getTimeAgo((10000000000000L - result.getTimestamp())));
textFeed.optionA_layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (result.getAnswer().equals("a")) {
Log.e("AAAAnswer- ", result.getAnswer());
textFeed.optionA_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else {
Log.e("Answer- ", result.getAnswer());
textFeed.optionA_layout.setBackgroundColor(context.getResources().getColor(R.color.wrong_answer));
if (result.getAnswer().equals("b")) {
textFeed.optionB_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("c")) {
textFeed.optionC_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("d")) {
textFeed.optionD_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
}
}
if (textFeed.descView.getVisibility() == View.GONE) {
textFeed.descView.setVisibility(View.VISIBLE);
}
}
});
textFeed.optionB_layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (result.getAnswer().equals("b")) {
Log.e("BBBAnswer- ", result.getAnswer());
textFeed.optionB_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else {
textFeed.optionB_layout.setBackgroundColor(context.getResources().getColor(R.color.wrong_answer));
if (result.getAnswer().equals("a")) {
textFeed.optionA_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("c")) {
textFeed.optionC_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("d")) {
textFeed.optionD_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
}
}
if (textFeed.descView.getVisibility() == View.GONE) {
textFeed.descView.setVisibility(View.VISIBLE);
}
}
});
textFeed.optionC_layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (result.getAnswer().equals("c")) {
Log.e("CCCAnswer- ", result.getAnswer());
textFeed.optionC_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else {
textFeed.optionC_layout.setBackgroundColor(context.getResources().getColor(R.color.wrong_answer));
if (result.getAnswer().equals("b")) {
textFeed.optionB_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("a")) {
textFeed.optionA_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("d")) {
textFeed.optionD_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
}
}
if (textFeed.descView.getVisibility() == View.GONE) {
textFeed.descView.setVisibility(View.VISIBLE);
}
}
});
textFeed.optionD_layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (result.getAnswer().equalsIgnoreCase("d")) {
Log.e("DDDAnswer- ", result.getAnswer());
textFeed.optionD_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else {
Log.e("DDDAnswer- ", result.getAnswer());
textFeed.optionD_layout.setBackgroundColor(context.getResources().getColor(R.color.wrong_answer));
if (result.getAnswer().equals("b")) {
textFeed.optionB_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("c")) {
textFeed.optionC_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
} else if (result.getAnswer().equals("a")) {
textFeed.optionA_layout.setBackgroundColor(context.getResources().getColor(R.color.right_answer));
}
}
if (textFeed.descView.getVisibility() == View.GONE) {
textFeed.descView.setVisibility(View.VISIBLE);
}
}
});
break;
}
}
#Override
public int getItemCount() {
return postResults == null ? 0 : postResults.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return QUESTION;
}
public void add(PostRead r) {
postResults.add(r);
notifyItemInserted(postResults.size() - 1);
}
public void addAll(List<PostRead> moveResults) {
for (PostRead result : moveResults) {
add(result);
}
notifyDataSetChanged();
}
public void remove(PostRead r) {
int position = postResults.indexOf(r);
if (position > -1) {
postResults.remove(position);
notifyItemRemoved(position);
}
}
public void clear() {
isLoadingAdded = false;
while (getItemCount() > 0) {
remove(getItem(0));
}
}
public boolean isEmpty() {
return getItemCount() == 0;
}
public void addLoadingFooter() {
isLoadingAdded = true;
add(new PostRead());
}
public void removeLoadingFooter() {
isLoadingAdded = false;
int position = postResults.size() - 1;
PostRead result = getItem(position);
if (result != null) {
postResults.remove(position);
notifyItemRemoved(position);
}
}
public PostRead getItem(int position) {
return postResults.get(position);
}
protected class QuestionFeed extends RecyclerView.ViewHolder {
private ImageView back, share;
private MyTextView question;
private MyTextView optionA, optionB, optionC, optionD, answerView, time;
private LinearLayout optionA_layout, optionB_layout, optionC_layout, optionD_layout, errorLayout, descView;
private ProgressBar mProgress;
private Button btnRetry;
private TextView txtError;
private RelativeLayout mainLayout, backButton;
public QuestionFeed(View itemView) {
super(itemView);
back = (ImageView) itemView.findViewById(R.id.backView);
back = (ImageView) itemView.findViewById(R.id.share);
question = (MyTextView) itemView.findViewById(R.id.question);
optionA = (MyTextView) itemView.findViewById(R.id.optionA);
optionB = (MyTextView) itemView.findViewById(R.id.optionB);
optionC = (MyTextView) itemView.findViewById(R.id.optionC);
optionD = (MyTextView) itemView.findViewById(R.id.optionD);
answerView = (MyTextView) itemView.findViewById(R.id.subject);
time = (MyTextView) itemView.findViewById(R.id.time);
optionA_layout = (LinearLayout) itemView.findViewById(R.id.optionbuttonA);
optionB_layout = (LinearLayout) itemView.findViewById(R.id.optionbuttonB);
optionC_layout = (LinearLayout) itemView.findViewById(R.id.optionbuttonC);
optionD_layout = (LinearLayout) itemView.findViewById(R.id.optionbuttonD);
mProgress = (ProgressBar) itemView.findViewById(R.id.main_progress);
mainLayout = (RelativeLayout) itemView.findViewById(R.id.content_sign_up);
backButton = (RelativeLayout) itemView.findViewById(R.id.back_button);
descView = (LinearLayout) itemView.findViewById(R.id.desc);
errorLayout = (LinearLayout) itemView.findViewById(R.id.error_layout);
btnRetry = (Button) itemView.findViewById(R.id.error_btn_retry);
txtError = (TextView) itemView.findViewById(R.id.error_txt_cause);
}
}
Fragment Code
private void loadFirstPage() {
hideErrorView();
Query query = postRef.orderByChild("timestamp").startAt(firstTime).limitToFirst(14);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
final List<PostRead> allPosts = new ArrayList<>();
childCount = (int) dataSnapshot.getChildrenCount();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
// TODO: handle the post
Log.e("Online ", "" + firstTime);
PostRead catItems = postSnapshot.getValue(PostRead.class);
catItems.setPostkey(postSnapshot.getKey());
allPosts.add(catItems);
childCount--;
if (childCount == 0) {
firstStart = 0;
dataBaseHelper.updatePosts(allPosts);
hideErrorView();
progressBar.setVisibility(View.GONE);
adapter.addAll(allPosts);
isLoading = false;
if (allPosts.size() == 0) {
isLastPage = true;
} else adapter.addLoadingFooter();
}
firstTime = catItems.getTimestamp();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
That is because Views are recycled by RecyclerView and you are setting background color to different color manually.
The solution is to set default color for background of your textFeed in BindViewHolder as:
textFeed.optionA_layout.setBackgroundColor(context.getResources().getColor(R.color.default_color));
textFeed.optionB_layout.setBackgroundColor(context.getResources().getColor(R.color.default_color));
textFeed.optionC_layout.setBackgroundColor(context.getResources().getColor(R.color.default_color));
textFeed.optionD_layout.setBackgroundColor(context.getResources().getColor(R.color.default_color));

Getting an IndexOutOfBoundsException error while implementing pagination in a RecyclerView

I have been very meticulous in following this guide to implement pagination in my RecyclerView. Only difference is I'm using Retrofit to retrieve data from the API.
When I open my activity it stops after a while, and when I check Logcat, it says: IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{31a22aa position=4 id=-1, oldPos=2,... This is what my RecyclerView adapter looks like:
public class CuratedSectionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static int VIEW_TYPE_HEADER = 0;
private static int VIEW_TYPE_ITEM = 1;
private static int VIEW_TYPE_LOADING = 2;
private RecyclerView mRecyclerView;
private OnLoadMoreListener mOnLoadMoreListener;
private boolean isLoading;
private int visibleThreshold = 2;
private int lastVisibleItem, totalItemCount;
private List<Object> itemList;
public CuratedSectionAdapter(List<Object> itemList, RecyclerView recyclerView, LinearLayoutManager layoutManager) {
this.itemList = itemList;
this.mRecyclerView = recyclerView;
final LinearLayoutManager linearLayoutManager = layoutManager;
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
totalItemCount = linearLayoutManager.getItemCount();
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
if (!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
if (mOnLoadMoreListener != null) {
mOnLoadMoreListener.onLoadMore();
}
isLoading = true;
}
}
});
}
public void setOnLoadMoreListener(OnLoadMoreListener mOnLoadMoreListener) {
this.mOnLoadMoreListener = mOnLoadMoreListener;
}
private class ItemViewHolder extends RecyclerView.ViewHolder {
RecyclerView itemRecyclerView;
CuratedSectionNestedAdapter nestedAdapter;
LinearLayoutManager layoutManager;
ItemViewHolder(View view) {
super(view);
itemRecyclerView = view.findViewById(R.id.recyclerView_nested);
layoutManager = new LinearLayoutManager(view.getContext(), LinearLayoutManager.HORIZONTAL, false);
}
}
private class HeaderViewHolder extends RecyclerView.ViewHolder {
TextView textViewHeader;
Typeface montserratMedium = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/Montserrat-Medium.ttf");
HeaderViewHolder(View view) {
super(view);
textViewHeader = view.findViewById(R.id.textView_header);
textViewHeader.setTypeface(montserratMedium);
}
}
private class LoadingViewHolder extends RecyclerView.ViewHolder {
ProgressBar progressBar;
LoadingViewHolder(View itemView) {
super(itemView);
progressBar = itemView.findViewById(R.id.progress_bar);
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder.getItemViewType() == VIEW_TYPE_HEADER) {
HeaderViewHolder viewHolder = (HeaderViewHolder) holder;
CuratedSectionHeader header = (CuratedSectionHeader) itemList.get(position);
viewHolder.textViewHeader.setText(header.getHeaderName());
} else if (holder.getItemViewType() == VIEW_TYPE_ITEM){
ItemViewHolder viewHolder = (ItemViewHolder) holder;
List<CuratedSectionItem> items = (List<CuratedSectionItem>) itemList.get(position);
if (viewHolder.nestedAdapter != null) {
viewHolder.nestedAdapter.setItems(items);
} else {
viewHolder.nestedAdapter = new CuratedSectionNestedAdapter(items);
viewHolder.itemRecyclerView.setLayoutManager(viewHolder.layoutManager);
viewHolder.itemRecyclerView.setAdapter(viewHolder.nestedAdapter);
}
} else if (holder.getItemViewType() == VIEW_TYPE_LOADING){
LoadingViewHolder viewHolder = (LoadingViewHolder) holder;
viewHolder.progressBar.setIndeterminate(true);
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_HEADER) {
return new HeaderViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.main_explore_header_row, parent, false));
} else if (viewType == VIEW_TYPE_ITEM) {
return new ItemViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.main_explore_row, parent, false));
} else if (viewType == VIEW_TYPE_LOADING) {
return new LoadingViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_loading_item, parent, false));
}
throw new RuntimeException("Adapter " + viewType + "not found");
}
#Override
public int getItemCount() {
return itemList.size();
}
#Override
public int getItemViewType(int position) {
if(isHeader(position)) {
return VIEW_TYPE_HEADER;
} else if(isLoading(position)) {
return VIEW_TYPE_LOADING;
} else {
return VIEW_TYPE_ITEM;
}
}
public boolean isHeader(int position) {
return itemList.get(position) instanceof CuratedSectionHeader;
}
public boolean isLoading(int position) {
return position > itemList.size();
}
public void setLoaded() {
isLoading = false;
}
}
It may have something to do with how I constructed LoadingViewHolder, but I think I did that one correctly. On the other hand, this is what the activity looks like:
public class ExploreFeedActivity extends Activity {
private RecyclerView recyclerView;
private CuratedSectionAdapter curatedSectionAdapter;
private LinearLayoutManager layoutManager;
private Sections curated;
int mStart = 0;
int mLimit = 2;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_explore);
curated = new Sections();
curated.loadSections(mStart, mLimit);
recyclerView = findViewById(R.id.recycler_view_main);
layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
}
private class Sections {
ArrayList<CuratedSection> sections = new ArrayList<>();
public Thread[] thread;
private Sections() {}
public void setSections(ArrayList<CuratedSection> sections) {
this.sections = sections;
}
public void setSectionStories(String sectionId, List<CuratedSectionItem> stories) {
for(CuratedSection s : sections){
if(s.id != null && s.id.equals(sectionId)) {
s.stories = stories;
}
}
}
public void loadStories(String sessionKey) {
thread = new Thread[sections.size()];
for( int s = 0; s < sections.size(); s++) {
thread[s] = new Thread(new LoadStories(sessionKey, sections.get(s)));
thread[s].start();
}
for( int f = 0; f < sections.size(); f++) {
try {
thread[f].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
curatedSectionAdapter = new CuratedSectionAdapter(this.getAdapterInfo(), recyclerView, layoutManager);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(curatedSectionAdapter);
curatedSectionAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
#Override
public void onLoadMore() {
Log.e("haint", "Load More");
curated.sections.add(null);
curatedSectionAdapter.notifyItemInserted(curated.sections.size() - 1);
// Load more data for recyclerview
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Log.e("haint", "Load Further");
// Remove loading item
curated.sections.remove(curated.sections.size() - 1);
curatedSectionAdapter.notifyItemRemoved(curated.sections.size());
// Load data
curated.loadSections(2, 2);
curatedSectionAdapter.notifyDataSetChanged();
curatedSectionAdapter.setLoaded();
}
}, 5000);
}
});
}
public void loadSections(int start, int limit) {
swipeRefreshLayout.setRefreshing(false);
LoadSections load = new LoadSections(start, limit);
load.run();
}
public List<Object> getAdapterInfo() {
List<Object> list = new ArrayList<>();
for (int i = 0; i < sections.size(); i++) {
CuratedSection section = sections.get(i);
CuratedSectionHeader header = new CuratedSectionHeader();
header.setHeaderName(section.header);
list.add(header);
list.add(section.stories);
}
return list;
}
}
private class LoadSections implements Runnable {
int start, limit;
LoadSections(int start, int limit) {
this.start = start;
this.limit = limit;
}
#Override
public void run() {
SharedPreferences prefs = getSharedPreferences("user_session", MODE_PRIVATE);
final String sessionKey = prefs.getString("session_key", null);
Call<JsonArray> call;
call = TravelersApi.endpoint().getCuratedSections(sessionKey);
call.enqueue(new Callback<JsonArray>() {
#Override
public void onResponse(Call<JsonArray> call, Response<JsonArray> response) {
if(response.code() != 200) {
Toast.makeText(getApplicationContext(), "Cannot load page as of the moment.", Toast.LENGTH_SHORT).show();
return;
}
JsonArray rawSections = response.body();
if(rawSections.size() == 0) {
//TODO: show placeholder
return;
}
for(int i = start; i < start+limit; i++) {
JsonObject jSection = rawSections.get(i).getAsJsonObject();
final CuratedSection section = new CuratedSection();
section.id = jSection.get("id").getAsString();
section.header = jSection.get("section_header").getAsString();
section.isShown = jSection.get("is_shown").getAsBoolean();
section.stories = new ArrayList<>();
curated.sections.add(section);
}
curated.setSections(curated.sections);
curated.loadStories(sessionKey);
}
#Override
public void onFailure(Call<JsonArray> call, Throwable t) {
Log.d("ERROR!", t.toString());
t.printStackTrace();
}
});
}
}
private class LoadStories implements Runnable {
String sessionKey;
CuratedSection section;
LoadStories(String sessionKey, CuratedSection section) {
this.sessionKey = sessionKey;
this.section = section;
}
#Override
public void run() {
Call<JsonArray> subCall;
subCall = TravelersApi.endpoint().getCuratedSectionTopics(sessionKey, section.id);
try {
Response<JsonArray> response = subCall.execute();
if(response.code() != 200) {
Toast.makeText(getApplicationContext(), "Cannot load page as of the moment.", Toast.LENGTH_SHORT).show();
return;
}
JsonArray rawStories = response.body();
if(rawStories.size() == 0) {
//TODO: show placeholder
return;
}
ArrayList<CuratedSectionItem> stories = new ArrayList<>();
for(int i = 0; i < rawStories.size(); i++) {
JsonObject jStories = rawStories.get(i).getAsJsonObject();
JSONObject temp = new JSONObject(jStories.toString());
JsonObject author = jStories.get("author").getAsJsonObject();
CuratedSectionItem story = new CuratedSectionItem();
story.title = jStories.get("title").getAsString();
story.avatar = author.get("profile_photo").getAsString();
stories.add(story);
}
section.stories = stories;
} catch (IOException e) {
Log.d("ERROR!", e.toString());
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
It's interesting to note that my RecyclerView adapter curatedSectionAdapter was instantiated in the method loadStories inside the private class Sections. I have tried moving that part to onCreate but then the activity won't display anything. I also suspect that the way I constructed the for loop in the callback in LoadSections has something to do with the crash.

Duplicate value append in recycleview multiple view android pagination

i m integrate recycleview with multiple view so below is my code
public class ActivityProdcutListWithMulipleView extends AppCompatActivity {
RecyclerView mRecyclerView;
Toolbar mToolbar;
PostParseGet mPostParseGet;
AllMethods mAllMethods;
GetProductListing mGetProductListing;
RecyclerView.LayoutManager mLayoutManager;
ProgressDialog mProgressDialog;
int page = 1;
int total = 0;
int totalFeature = 0;
int totalbanner = 0;
ImageView mImageViewBack;
ArrayList<GetProductListing.ListingBlock> mListingBlocks;
ArrayList<GetProductListing.ListingBlock> mListingBlocksFeature;
ArrayList<GetProductListing.ListingBlock> mListingBlocksBanner;
ArrayList<OrderItemDemo> mOrderItemDemos = new ArrayList<OrderItemDemo>();
GridLayoutManager mLayoutManagerGrid;
DifferentRowAdapter adapter;
private Handler handler;
ArrayList<GetProductListing.ListingBlock> adapterData;
public static Activity mActivity;
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_product_list);
mListingBlocks = new ArrayList<>();
mActivity = this;
mListingBlocksFeature = new ArrayList<>();
mListingBlocksBanner = new ArrayList<>();
mRecyclerView = (RecyclerView) findViewById(R.id.recycle);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mImageViewBack = (ImageView) mToolbar.findViewById(R.id.imgBack);
WebAPIApplication.mArrayListingAllProductBlocks.clear();
mPostParseGet = new PostParseGet(ActivityProdcutListWithMulipleView.this);
mAllMethods = new AllMethods(ActivityProdcutListWithMulipleView.this);
mGetProductListing = new GetProductListing();
mLayoutManagerGrid = new GridLayoutManager(ActivityProdcutListWithMulipleView.this, 2);
mLayoutManager = new LinearLayoutManager(ActivityProdcutListWithMulipleView.this);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(mLayoutManagerGrid);
handler = new Handler();
adapterData = new ArrayList<>();
mRecyclerView.addOnScrollListener(new EndlessRecyclerGridOnScrollListener(mLayoutManagerGrid) {
#Override
public void onLoadMore(int current_page) {
if (WebAPIApplication.mArrayListingAllProductBlocks.size() < total) {
page++;
new getProductData(false, true).execute();
}
}
});
adapter = new DifferentRowAdapter(mOrderItemDemos);
mRecyclerView.setAdapter(adapter);
mLayoutManagerGrid.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
return adapter.getItemViewType(position) == OrderItemDemo.BANNER_TYPE ? 2 : 1;
}
});
if (mAllMethods.check_Internet() == true) {
new getProductData(true, false).execute();
} else {
mAllMethods.ShowDialog(ActivityProdcutListWithMulipleView.this, "", getString(R.string.net_not_available), "OK");
}
mImageViewBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
}
public static class DifferentRowAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private int visibleThreshold = 5;
private int lastVisibleItem, totalItemCount;
private boolean loading;
boolean isLoading = false, isMoreDataAvailable = true;
private List<OrderItemDemo> mList;
OnLoadMoreListener loadMoreListener;
public DifferentRowAdapter(List<OrderItemDemo> list) {
this.mList = list;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case OrderItemDemo.NORMAL_TYPE:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_list_file, parent, false);
return new ProductListRow(view);
case OrderItemDemo.FEATURE_TYPE:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_list_feature_file, parent, false);
return new ProductListRow(view);
case OrderItemDemo.BANNER_TYPE:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_list_file, parent, false);
return new ProductListRow(view);
}
return null;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) {
isLoading = true;
loadMoreListener.onLoadMore();
}
final OrderItemDemo object = mList.get(position);
if (object != null) {
switch (object.getmType()) {
case OrderItemDemo.NORMAL_TYPE:
((ProductListRow) holder).name.setText(object.getId() + " " + object.getTitle());
((ProductListRow) holder).price.setText(object.getType());
Picasso.with(mActivity)
.load(object.getImage())
.into(((ProductListRow) holder).mImageViewProduct);
((ProductListRow) holder).mImageViewBanner.setVisibility(View.GONE);
((ProductListRow) holder).mRelativeLayout.setVisibility(View.VISIBLE);
break;
case OrderItemDemo.FEATURE_TYPE:
((ProductListRow) holder).name.setText(object.getId() + " " + object.getTitle());
((ProductListRow) holder).price.setText(object.getType());
((ProductListRow) holder).mImageViewBanner.setVisibility(View.GONE);
((ProductListRow) holder).mRelativeLayout.setVisibility(View.VISIBLE);
Picasso.with(mActivity)
.load(object.getImage())
.into(((ProductListRow) holder).mImageViewProduct);
break;
case OrderItemDemo.BANNER_TYPE:
((ProductListRow) holder).price.setText(object.getType());
((ProductListRow) holder).mImageViewBanner.setVisibility(View.VISIBLE);
((ProductListRow) holder).mRelativeLayout.setVisibility(View.GONE);
break;
}
}
}
public void setMoreDataAvailable(boolean moreDataAvailable) {
isMoreDataAvailable = moreDataAvailable;
}
public void notifyDataChanged() {
notifyDataSetChanged();
isLoading = false;
}
interface OnLoadMoreListener {
void onLoadMore();
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
#Override
public int getItemCount() {
if (mList == null)
return 0;
return mList.size();
}
#Override
public int getItemViewType(int position) {
if (mList != null) {
OrderItemDemo object = mList.get(position);
if (object != null) {
return object.getmType();
}
}
return 0;
}
}
public abstract class EndlessRecyclerGridOnScrollListener extends
RecyclerView.OnScrollListener {
public String TAG = EndlessRecyclerGridOnScrollListener.class
.getSimpleName();
private int previousTotal = 0;
private boolean loading = true;
private int visibleThreshold = 5;
int firstVisibleItem, visibleItemCount, totalItemCount;
private int current_page = 1;
private LinearLayoutManager mLinearLayoutManager;
public EndlessRecyclerGridOnScrollListener(
GridLayoutManager linearLayoutManager) {
this.mLinearLayoutManager = linearLayoutManager;
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = recyclerView.getChildCount();
totalItemCount = mLinearLayoutManager.getItemCount();
firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();
visibleThreshold = total;
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading
&& (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
// End has been reached
// Do something
current_page++;
onLoadMore(current_page);
loading = true;
}
}
public abstract void onLoadMore(int current_page);
}
public class getProductData extends AsyncTask<Void, Void, Void> {
boolean showLoading;
boolean pagination;
public getProductData(boolean showLoading, boolean page) {
this.showLoading = showLoading;
this.pagination = page;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
if (showLoading == true) {
mProgressDialog = ProgressDialog.show(ActivityProdcutListWithMulipleView.this, "", "Loading..");
}
}
#Override
protected Void doInBackground(Void... voids) {
mGetProductListing = (GetProductListing) mPostParseGet.getTopSearchData(mGetProductListing, page);
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (showLoading == true) {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
}
}
if (mGetProductListing != null) {
try {
total = Integer.parseInt(mGetProductListing.getListing().getTotal());
if (mGetProductListing.getListing().getData().size() > 0) {
mListingBlocks = getProductBlock();
Log.e("FeatureSize", String.valueOf(mListingBlocksFeature.size()));
Log.e("BannerSize", String.valueOf(mListingBlocksBanner.size()));
for (int i = 0; i < WebAPIApplication.mArrayListingAllProductBlocks.size(); i++) {
if (WebAPIApplication.mArrayListingAllProductBlocks.get(i).getType().equalsIgnoreCase("product")) {
mOrderItemDemos.add(new OrderItemDemo(WebAPIApplication.mArrayListingAllProductBlocks.get(i).getId(), WebAPIApplication.mArrayListingAllProductBlocks.get(i).getTitle(), WebAPIApplication.mArrayListingAllProductBlocks.get(i).getType(), WebAPIApplication.mArrayListingAllProductBlocks.get(i).getMedium_image(), OrderItemDemo.NORMAL_TYPE));
} else if (WebAPIApplication.mArrayListingAllProductBlocks.get(i).getType().equalsIgnoreCase("featured")) {
mOrderItemDemos.add(new OrderItemDemo(WebAPIApplication.mArrayListingAllProductBlocks.get(i).getId(), WebAPIApplication.mArrayListingAllProductBlocks.get(i).getTitle(), WebAPIApplication.mArrayListingAllProductBlocks.get(i).getType(), WebAPIApplication.mArrayListingAllProductBlocks.get(i).getMedium_image(), OrderItemDemo.FEATURE_TYPE));
} else {
mOrderItemDemos.add(new OrderItemDemo(WebAPIApplication.mArrayListingAllProductBlocks.get(i).getId(), WebAPIApplication.mArrayListingAllProductBlocks.get(i).getTitle(), WebAPIApplication.mArrayListingAllProductBlocks.get(i).getType(), WebAPIApplication.mArrayListingAllProductBlocks.get(i).getMedium_image(), OrderItemDemo.BANNER_TYPE));
}
}
adapter = new DifferentRowAdapter(mOrderItemDemos);
if (pagination == false) {
mRecyclerView.setAdapter(adapter);
}
adapter.notifyDataSetChanged();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/*Get Product data */
public ArrayList<GetProductListing.ListingBlock> getProductBlock() {
ArrayList<GetProductListing.ListingBlock> mArrayListParserLog = new ArrayList<GetProductListing.ListingBlock>();
for (int i = 0; i < mGetProductListing.getListing().getData().size(); i++) {
GetProductListing.ListingBlock mParserLog = new GetProductListing.ListingBlock();
mParserLog.setId(mGetProductListing.getListing().getData().get(i).getId());
mParserLog.setType(mGetProductListing.getListing().getData().get(i).getType());
mParserLog.setTitle(mGetProductListing.getListing().getData().get(i).getTitle());
mParserLog.setDiscountSale(mGetProductListing.getListing().getData().get(i).getDiscountSale());
mParserLog.setDiscountSelling(mGetProductListing.getListing().getData().get(i).getDiscountSelling());
mParserLog.setPrice(mGetProductListing.getListing().getData().get(i).getPrice());
mParserLog.setAupc(mGetProductListing.getListing().getData().get(i).getAupc());
mParserLog.setSale_end(mGetProductListing.getListing().getData().get(i).getSale_end());
mParserLog.setSale_start(mGetProductListing.getListing().getData().get(i).getSale_start());
mParserLog.setSelling_price(mGetProductListing.getListing().getData().get(i).getSelling_price());
mParserLog.setProduct_rating(mGetProductListing.getListing().getData().get(i).getProduct_rating());
mParserLog.setSlug(mGetProductListing.getListing().getData().get(i).getSlug());
mParserLog.setSold_out(mGetProductListing.getListing().getData().get(i).getSold_out());
mParserLog.setImage(mGetProductListing.getListing().getData().get(i).getImage());
mParserLog.setSku_id(mGetProductListing.getListing().getData().get(i).getSku_id());
mParserLog.setMedium_image(mGetProductListing.getListing().getData().get(i).getMedium_image());
mArrayListParserLog.add(mParserLog);
WebAPIApplication.mArrayListingAllProductBlocks.add(mParserLog);
}
return mArrayListParserLog;
}
}
When i run above code in first page i get proper value but when i call second page at that time first page value will append again with second page data so any idea how can i solve this ? your all suggestions are appreciable
Try arraylist.clear() before loading Updated data into ArrayList to Avoid Duplicate Values.
1.Add this Code Before Oncreate
ArrayList<GetProductListing.ListingBlock> mArrayListParserLog = new ArrayList<GetProductListing.ListingBlock>();
and remove it from getProductBlock()
Add mArrayListParserLog.clear(); with in getProductBlock() method
public ArrayList<GetProductListing.ListingBlock> getProductBlock(){
mArrayListParserLog.clear();

Categories

Resources