Search code examples
javaandroidandroid-recyclerviewandroid-adapterandroid-viewmodel

RecyclerView only shows new items when more items are added


I have a RecyclerView with endless scrolling. When the fragment opens it loads the first ten items in to the RecyclerView, all good. But when it loads the next ten items, instead of adding them to the excisting items, it removes the old items and only shows the new items.

So my question is: why is it not keeping the old items when I load more?

I am using the Endless Scrolling from here.

Fragment.java


public class twoFragment extends Fragment implements LifecycleOwner {

    private twoViewModel twoViewModel;
    private RecyclerView recyclerView;
    private RecyclerViewAdapter recyclerViewAdapter;
    private EndlessRecyclerViewScrollListener scrollListener;
    WebRequest webRequest  = new WebRequest();

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        System.out.println("************ onCreateView ***********");

        System.out.println("************ ViewModelProvider ***********");
        twoViewModel = new ViewModelProvider(this).get(twoViewModel.class);
        View root = inflater.inflate(R.layout.two, container, false);
        recyclerView = root.findViewById(R.id.rv_main);
        recyclerView.setHasFixedSize(true);


        recyclerViewAdapter = new RecyclerViewAdapter(requireActivity());
        final int columns = getResources().getInteger(R.integer.gallery_columns);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(requireActivity(), columns);
        recyclerView.setLayoutManager(gridLayoutManager);



       // Endless scrolling
        scrollListener = new EndlessRecyclerViewScrollListener(gridLayoutManager) {
            @Override
            public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
                // Triggered only when new data needs to be appended to the list
                // Add whatever code is needed to append new items to the bottom of the list
                System.out.println("************ onLoadMore >>> EndlessRecyclerViewScrollListener ***********");
                System.out.println("************ onLoadMore >>> page  ***********" + page);

             
                webRequest.MakeRequest("BROWSE_REQUEST", page +1, "",  twoViewModel.getUserMutableLiveData());


            }
        };
        // Adds the scroll listener to RecyclerView
        recyclerView.addOnScrollListener(scrollListener);


        twoViewModel.getUserMutableLiveData().observe(getViewLifecycleOwner(),userListUpdateObserver);
        

        return root;
        };

        private Observer<ArrayList<User>> userListUpdateObserver = new Observer<ArrayList<User>>() {
            @Override
            public void onChanged(ArrayList<User> userArrayList) {
                System.out.println("************ onChanged ***********");
                 recyclerView.setAdapter(recyclerViewAdapter);
                ((RecyclerViewAdapter)recyclerView.getAdapter()).setData(userArrayList);
                
            }
        };

}

RecyclerViewAdapter.java

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    Activity context;
    private ArrayList<User> userArrayList;
    public RecyclerViewAdapter(Activity context) {
        this.context = context;
        this.userArrayList = userArrayList;

    }

    public void setData(ArrayList<User> userArrayListOne){
        userArrayList = userArrayListOne;
        notifyDataSetChanged();
        System.out.println("%% %% notifyDataSetChanged %% %%");
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        System.out.println("************ onCreateViewHolder ***********");
        View rootView = LayoutInflater.from(context).inflate(R.layout.item,parent,false);
        return new RecyclerViewViewHolder(rootView);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        System.out.println("************ onBindViewHolder ***********");
        User user = userArrayList.get(position);
        RecyclerViewViewHolder viewHolder= (RecyclerViewViewHolder) holder;

        // Set title as HTML code on view
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            viewHolder.txtView_title.setText(Html.fromHtml(user.getTitle(), Html.FROM_HTML_MODE_COMPACT));
        } else {
            viewHolder.txtView_title.setText(Html.fromHtml(user.getTitle()));
        }

        viewHolder.txtView_description.setText(user.getDescription()); // TODO add error png
        Glide.with(context).load(user.getImagePath()).centerInside().error(R.drawable.yahushuas_commands_pt__2).into(viewHolder.imgView_icon);

    }

    @Override
    public int getItemCount() {
            return userArrayList.size();
    }

    class RecyclerViewViewHolder extends RecyclerView.ViewHolder {
        ImageView imgView_icon;
        TextView txtView_title;
        TextView txtView_description;

        public RecyclerViewViewHolder(@NonNull View itemView) {
            super(itemView);
            imgView_icon = itemView.findViewById(R.id.imgView_icon);
            txtView_title = itemView.findViewById(R.id.txtView_title);
            txtView_description = itemView.findViewById(R.id.txtView_description);


        }
    }
}

Solution

  • In RecyclerViewAdapter.java's setData method you are updating the userArrayList by assigning new ArrayList each time. For this reason the old data is getting replaced. You need to add the new data to existing list.

    private ArrayList<User> userArrayLis = new ArrayList<User>(); // Initialise the arraylist
    
    public void setData(ArrayList<User> userArrayListOne){
        userArrayList.addAll(userArrayListOne);
        notifyDataSetChanged();
    }