Recyclerview Changing Items During Scroll

89,807

Solution 1

Please try this

  1. If you are using ListView - override the following methods.

     @Override
     public int getViewTypeCount() {    
         return getCount();
     }
    
     @Override
     public int getItemViewType(int position) {    
         return position;
     }
    
  2. If you are using RecyclerView - override only getItemViewType() method.

     @Override
     public int getItemViewType(int position) {    
         return position;
     }
    

Solution 2

Add setHasStableIds(true); in your adapter constructor and Override these two methods in adapter. It also worked if anyone using a RecyclerView inside a ViewPager which is also inside a NestedScrollView.

@Override
public long getItemId(int position) {
            return position;
}

@Override
public int getItemViewType(int position) {
       return position;
}

Solution 3

As the name implies, the views in a RecyclerView are recycled as you scroll down. This means that you need to keep the state of each item in your backing model, which in this case would be a Historyitem, and restore it in your onBindViewHolder.

1) Create position, max, and whatever other variables you need to save the state of the ProgressBar in your model.

2) Set the state of your ProgressBar based on the data in your backing model; on click, pass the position of the item to your FileDownload/StartMediaPlayer methods.

public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, int position) {
    final Historyitem dataItem = stethitems.get(position);
    final MyViewHolder myViewHolder = (MyViewHolder) viewHolder;
    myViewHolder.progressplay.setMax(dataItem.getMax());
    myViewHolder.progressplay.setProgress(dataItem.getPosition());
    ...
    myViewHolder.stethstreamplay.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
               FileDownload(dataItem.getmsg(), position);
        }
    });

3) Update the progress bar by updating the backing model and notifying that it was changed.

stethitems.get(position).setPosition(mPlayer.getCurrentPosition());
notifyItemChanged(position);

Solution 4

I have faced the same problem while I was trying to implement a recyclerview that contains a edittex and a checkbox as a row elements. I solved the scrolling value changing problem just by adding the following two lines in the adapter class.

@Override
public long getItemId(int position) {
    return position;
}

@Override
public int getItemViewType(int position) {
    return position;
}

I hope it will be a possible solution. Thanks

Solution 5

recyclerview.setItemViewCacheSize(YourList.size());

Share:
89,807
Arya
Author by

Arya

Updated on July 14, 2022

Comments

  • Arya
    Arya almost 2 years

    I have a RecyclerView. Each row has a play button, textview and Progressbar. when click on the play button have to play audio from my sdcard and have to progress Progressbar The problem is when i scroll down the recyclerview change the Progressbar in next row.means I can fit 5 items on the screen at once. When I scroll to the 6th, 6th row seekbar changes suddenly.

    public class ListAdapter extends RecyclerView.Adapter {
    
        private List<Historyitem> stethitems;
        public Context mContext;
        public Activity activity;
        public Handler mHandler;
    
        static MediaPlayer mPlayer;
        static Timer mTimer;
    
        public ListAdapter(Activity activity,Context mContext,List<Historyitem> stethitems) {
            this.stethitems = stethitems;
            this.mContext = mContext;
            this.activity = activity;
        }
    
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    
            View rootView = LayoutInflater.
                    from(mContext).inflate(R.layout.stethoscopeadapteritem, null, false);
            RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            rootView.setLayoutParams(lp);
            mHandler = new Handler();
            return new MyViewHolder(rootView);
        }
    
        @Override
        public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, int position) {
    
            final Historyitem dataItem = stethitems.get(position);
            final MyViewHolder myViewHolder = (MyViewHolder) viewHolder;
            myViewHolder.progressplay.setProgress(0);
            myViewHolder.stethdatetime.setText(dataItem.getReported_Time());
            myViewHolder.stethhosname.setText(dataItem.getdiv());
    
            if(dataItem.getPatient_Attribute().replaceAll(" ","").equals("")){
                myViewHolder.stethdoctorname.setText(dataItem.getunit());
            } else {
                myViewHolder.stethdoctorname.setText(dataItem.getPatient_Attribute());
            }
    
            myViewHolder.stethstreamplay.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    
                       FileDownload(dataItem.getmsg(),
                                myViewHolder.progressplay);
    
                }
            });
        }
    
        @Override
        public int getItemCount() {
    
            return stethitems.size();
        }
    
        public class MyViewHolder extends RecyclerView.ViewHolder {
    
            final CustomTextRegular stethdatetime;
            final CustomTextView stethhosname;
            final CustomTextBold stethdoctorname;
            final ImageButton stethstreamplay;
            final NumberProgressBar progressplay;
    
            public MyViewHolder(View itemView) {
                super(itemView);
    
                stethdatetime = (CustomTextRegular)
                        itemView.findViewById(R.id.stethdatetime);
                stethhosname = (CustomTextView)
                        itemView.findViewById(R.id.stethhosname);
                stethdoctorname = (CustomTextBold)
                        itemView.findViewById(R.id.stethdoctorname);
                stethstreamplay = (ImageButton)
                        itemView.findViewById(R.id.stethstreamplay);
                progressplay= (NumberProgressBar)
                        itemView.findViewById(R.id.progressplay);
    
    
            }
        }
        public void  FileDownload(final String downloadpath,
    
                                         final NumberProgressBar progressplay) {
    
            new AsyncTask<NumberProgressBar, Integer, NumberProgressBar>() {
                NumberProgressBar progress;
                @Override
                protected void onPreExecute() {
                    super.onPreExecute();
                    try {
                        if(mPlayer!=null){
                            mPlayer.stop();
                        }
                    }catch (Exception e){
                    }
                    try {
                        if(mTimer != null){
                            mTimer.purge();
                            mTimer.cancel();
                        }
                    }catch (Exception e){
                    }
                }
    
                @Override
                protected NumberProgressBar doInBackground(NumberProgressBar... params) {
                    int count;
                    progress = progressplay;
                    try {
    
                        final List<NameValuePair> list = new ArrayList<NameValuePair>();
                        list.add(new BasicNameValuePair("pid",id));
    
                        URL url = new URL(Config.requestfiledownload + "?path=" +
                                downloadpath);
                        URLConnection connection = url.openConnection();
                        connection.connect();
    
                        int lenghtOfFile = connection.getContentLength();
                        // download the file
                        InputStream input = new BufferedInputStream(url.openStream());
                        OutputStream output = new FileOutputStream(Environment.getExternalStorageDirectory() +
                                "record.wav");
                        byte data[] = new byte[1024];
                        long total = 0;
                        while ((count = input.read(data)) != -1) {
                            total += count;
                            // publishing the progress....
                            publishProgress((int) (total * 100 / lenghtOfFile));
                            output.write(data, 0, count);
                        }
                        output.flush();
                        output.close();
                        input.close();
                    } catch (Exception e) {
    
                    }
                    return progress;
                }
                @Override
                protected void onPostExecute(final NumberProgressBar numberProgressBar) {
                    super.onPostExecute(numberProgressBar);
    
                            try {
                                StartMediaPlayer(numberProgressBar);
                            } catch (Exception e){
                                e.printStackTrace();
                            }
    
                }
            }.execute();
        }
    
        public void StartMediaPlayer(final NumberProgressBar progressbar){
            Uri playuri = Uri.parse("file:///sdcard/record.wav");
            mPlayer = new MediaPlayer();
            mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mPlayer.reset();
            try {
                mPlayer.setDataSource(mContext, playuri);
            } catch (IllegalArgumentException e) {
    
            } catch (SecurityException e) {
    
            } catch (IllegalStateException e) {
    
            } catch (Exception e) {
    
            }
            try {
                mPlayer.prepare();
            } catch (Exception e) {
    
            }
    
            mPlayer.start();
            progressbar.setMax(mPlayer.getDuration());
            mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    if(mPlayer!=null) {
                        mPlayer.release();
                        progressbar.setProgress(0);
                    }
                    if(mTimer != null){
                        mTimer.purge();
                        mTimer.cancel();
                    }
                }
            });
            mTimer = new Timer();
            mTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            progressbar.setProgress(mPlayer.getCurrentPosition());
                        }
                    });
                }
            },0,500);
        }}