web-dev-qa-db-fra.com

Tableau de recyclage Modification d'éléments pendant le défilement

J'ai un RecyclerView. Chaque ligne comporte un bouton de lecture, une vue du texte et une barre de progression. Lorsque vous cliquez sur le bouton de lecture, vous devez lire le son de ma carte SD et progresser. Progressbar Le problème est que lorsque je fais défiler la vue de recyclage, la barre de progression s'affiche dans la rangée suivante. Cela signifie que je peux insérer 5 éléments à la fois. Lorsque je me déplace vers la 6ème, la 6ème rangée, la barre de recherche change soudainement.

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);
    }}
53
Arya

S'il vous plaît essayer ceci

  1. Si vous utilisez ListView, remplacez les méthodes suivantes.

    @Override
    public int getViewTypeCount() {    
        return getCount();
    }
    
    @Override
    public int getItemViewType(int position) {    
        return position;
    }
    
  2. Si vous utilisez RecycyclerView - remplacez uniquement la méthode getItemViewType().

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

Ajoutez setHasStableIds(true); dans le constructeur de votre adaptateur et substituez ces deux méthodes à l'adaptateur.

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

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

Comme son nom l'indique, les vues d'un RecyclerView sont recyclées lorsque vous faites défiler l'écran. Cela signifie que vous devez conserver l'état de chaque élément dans votre modèle de support, qui dans ce cas serait un Historyitem, et le restaurer dans votre onBindViewHolder.

1) Créez la position, le maximum et toutes les autres variables dont vous avez besoin pour enregistrer l’état du ProgressBar dans votre modèle.

2) Définissez l’état de votre ProgressBar en fonction des données de votre modèle de sauvegarde; au clic, passez la position de l'élément à vos méthodes FileDownload/StartMediaPlayer.

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) Mettez à jour la barre de progression en mettant à jour le modèle de support et en notifiant qu'il a été modifié.

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

Mettez recylerView dans un NestedScroll View Dans votre XML et ajoutez la propriété nestedScrollingEnabled = false.

Et sur votre adaptateur onBindViewHolder ajoutez cette ligne

final MyViewHolder viewHolder = (MyViewHolder)holder;

Utilisez cet objet viewHolder avec vos vues pour setText ou faites n’importe quel type d’événement de clic.

par exemple viewHolder.txtSubject.setText("Example");

2
Indranil Chatterjee

J'ai rencontré le même problème lorsque j'essayais d'implémenter une vue recyclée qui contenait un edittex et une case à cocher en tant qu'éléments de ligne. J'ai résolu le problème de changement de valeur de défilement en ajoutant simplement les deux lignes suivantes dans la classe d'adaptateur.

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

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

J'espère que ce sera une solution possible. Merci

1
Shadat

Cette ligne change la progression en 0 sur chaque liaison

myViewHolder.progressplay.setProgress(0);

Sauvegardez son état quelque part puis chargez-le dans cette même ligne.

0
Ali Karaca

essaye ça

@Override public void smoothScrollToPosition(RecyclerView    recyclerView, RecyclerView.State state,
       int position) {    LinearSmoothScroller linearSmoothScroller =
           new LinearSmoothScroller(recyclerView.getContext()) {
               @Override
               public PointF computeScrollVectorForPosition(int targetPosition) {
                   return LinearLayoutManager.this
                           .computeScrollVectorForPosition(targetPosition);
               }
           };    linearSmoothScroller.setTargetPosition(position);    startSmoothScroll(linearSmoothScroller); }

voir aussi ceci

0
Vaishali Sutariya

Pourquoi n'essaies-tu pas comme ça,

    HashMap<String, Integer> progressHashMap = new HashMap<>();

    //...
    if(!progressHashMap.containsKey(downloadpath)){
        progressHashMap.put(downloadpath, mPlayer.getCurrentPosition());
    }

    progressbar.setProgress(progressHashMap.get(downloadpath));
0
saideveloper

J'ai eu le même problème en manipulant beaucoup de données, cela fonctionne avec 5 car il restitue les cinq éléments qui sont visibles à l'écran mais cela donne prob avec plus d'éléments. La chose est ..

Parfois, RecyclerView et listView ignorent simplement le remplissage des données. Si la fonction de liaison de RecyclerView est ignorée lors du défilement, mais lorsque vous essayez de déboguer l’adaptateur recyclerView, il fonctionnera correctement car il appellera onBind à chaque fois, vous pourrez également voir la vue officielle du développeur Google. The World of listView =. Environ 20 min à 30 min, ils vous expliqueront que vous ne pouvez jamais supposer que le getView par position sera appelé à chaque fois.

alors, je vais suggérer d'utiliser

RecyclerView DataBinder créé par satorufujiwara.

ou

Classeur RecyclerView MultipleViewTypes créé par yqritc.

Ce sont d'autres classeurs disponibles si vous trouvez ceux qui sont faciles à contourner.

C'est le moyen de traiter avec les types MultipleView ou si vous utilisez une grande quantité de données. Ces classeurs peuvent vous aider à lire attentivement la documentation qui l’aidera à résoudre le problème!

0
Hemant Shori