RPR
RPR

Reputation: 53

values of items are different after scroll the second time in RecyclerView

I am listing items that have a main picture and four thumb images below, to get them I first call to parsequery, after that they are displayed with the url . When I Scroll the first time everything looks good, but after first scrolling, if I have just two thumb images in any item, the consecuent thumbs 3 and 4 are displaying the thumb images of the first item. Here is the code, I've simplified it a litle

    public void onBindViewHolder(final VersionViewHolder versionViewHolder, final int i) {

      final Post itPost = items.get(i);

      versionViewHolder.itemView.setTag(itPost);

      ParseQuery<ParseObject> query = ParseQuery.getQuery("Images");
      query.whereEqualTo("postid", itPost.getIdPost());
      query.orderByDescending("createdAt");
      query.findInBackground(new FindCallback<ParseObject> () {
        @Override
        public void done(final List<ParseObject> objects, ParseException e) {
          if(e == null) {

            for(int o = 0; o < objects.size(); o++) {

              if(o == 0) {
                ImageUtil.displayImage(versionViewHolder.mainImg, objects.get(o).getString("url"), null);
              } else if(o == 1) {
                ImageUtil.displayImage(versionViewHolder.imgThumb, objects.get(o).getString("url"), null);
              } else if(o == 2) {
                ImageUtil.displayImage(versionViewHolder.imgThumb2, objects.get(o).getString("url"), null);
              } else if(o == 3) {
                ImageUtil.displayImage(versionViewHolder.imgThumb3, objects.get(o).getString("url"), null);
              } else if(o == 4) {

                ImageUtil.displayImage(versionViewHolder.imgThumb4, objects.get(o).getString("url"), null);

                versionViewHolder.imgThumb4.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                    //alertGallery(,versionViewHolder.itemView);
                  }

                });
              } else if(o <= 5) {

                String num = "" + o;
                versionViewHolder.txtContadorImagenes.setText("+ ");

                //TODO 
              }

            }

          }

        }
      });

Upvotes: 1

Views: 382

Answers (1)

bastien
bastien

Reputation: 2999

The problem comes from running the Parse query every time the onBindViewHolder() method is called and using the for loop.

You can also simplify the Parse table you are using. I am assuming that you wanted for each item, 1 main image and 4 thumbnails. Hence each ParseObject representing 1 item should contain the urls to the main image and the 4 thumbnails. You should not create a ParseObject for each url. 1 ParseObject = 1 item in the RecyclerView :)

  1. In Parse, rename url to urlMain and create the columns for the four thumbnails urlThumb1, urlThumb2, urlThumb3 and urlThumb4 with datatype String.
  2. Move your query outside the onBindViewHolder() method, say for instance to the onCreate() method of your Activity.
  3. In the done() callback of the Parse query, pass the query results list objects to your adapter and set the adapter on your RecyclerView.
  4. In onBindViewHolder() remove the for loop and use displayImage based on the ParseObject selected, determined by the position (of the item within the adapter's data set).

Code would look like:

  • in your activity and onCreate():

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // execute the parseQuery
            ParseQuery<ParseObject> query = ParseQuery.getQuery("Images");
            query.whereEqualTo("postid", itPost.getIdPost());
            query.orderByDescending("createdAt");
            query.findInBackground(new FindCallback<ParseObject> () {
                @Override
                public void done(final List<ParseObject> objects, ParseException e) {
                    if(e == null) {
                        // if no ParseException, pass the objects list to the adapter
                        YourAdapter yourAdapter = new YourAdapter(objects);
                        // set the adapter
                        yourRecyclerView.setAdapter(yourAdapter);
                    }
                }
            }
    
        ...
    
        }
    }
    
  • in your adapter

    public class YourAdapter extends RecyclerView.Adapter<YourViewHolder> {
        private List<ParseObject> list;
    
        public YourAdapter(List<ParseObject> objects) {
            list = objects;
        }
    
        ...
    
        // in the onBindViewHolder method, set the image based on the position
        @Override
        public void onBindViewHolder(YourViewHolder holder, int position) {
            ParseObject currentObj = list.get(position);
    
            ImageUtil.displayImage(holder.mainImg, currentObj.getString("urlMain"), null);
            ImageUtil.displayImage(holder.imgThumb, currentObj.getString("urlThumb1"), null);
            ImageUtil.displayImage(holder.imgThumb2, currentObj.getString("urlThumb2"), null);
            ImageUtil.displayImage(holder.imgThumb3, currentObj.getString("urlThumb3"), null);
            ImageUtil.displayImage(holder.imgThumb4, currentObj.getString("urlThumb4"), null);
    
            holder.imgThumb4.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //alertGallery(,versionViewHolder.itemView);
                }
        }
    }
    

Hopefully this helps, comment below if that is not what you wanted or have questions!

Upvotes: 1

Related Questions