Video showing in wrong order when using TextureView in ListView

I have a Listview that displays a video in some rows so that the user can view the video through the listview using a TextureView. So far the videos are loading and playing correctly, but they seem to appear in the wrong order at times when scrolling. I suppose it has something to do with looking at the adapter utility, but I'm not sure how to fix it.

here is my implementation

There is a getView that handles rendering of the views, and then an AsyncTask is created, triggered by getView to set up the MediaPlayer for each view.

@Override
public View getView(int position, View view, ViewGroup parent) {
    final ViewHolder holder;

    final VoucherItem vItem = items.get(position);

    if (view == null) {
        view = inflater.inflate(R.layout.voucher_row, parent, false);
        holder = new ViewHolder();

        holder.list_img = (ImageView) view.findViewById(R.id.list_img);         
        holder.vid_play = (ImageView) view.findViewById(R.id.vid_play);
        holder.video = (TextureView) view.findViewById(R.id.texture_video);

        view.setTag(holder);
    } else {
        holder = (ViewHolder) view.getTag();
    }



        if (!vItem.photo.equals(""))
            Picasso.with(context).load(vItem.photo).fit().centerCrop()
                    .into(holder.list_img);
        else
            Picasso.with(context).load(R.drawable.default_spuare).fit()
                    .centerCrop().into(holder.list_img);


        if (!vItem.photo.equals("")){
            holder.vid_play.setVisibility(View.GONE);
            holder.video.setVisibility(View.GONE);
            holder.list_img.setVisibility(View.VISIBLE);
        } else {                
            holder.video.setVisibility(View.VISIBLE);
            holder.list_img.setVisibility(View.GONE);

            holder.video.setSurfaceTextureListener(new SurfaceTextureListener() {

                @Override
                public void onSurfaceTextureUpdated(SurfaceTexture arg0) {

                }

                @Override
                public void onSurfaceTextureSizeChanged(SurfaceTexture arg0, int arg1,
                        int arg2) {                     
                }

                @Override
                public boolean onSurfaceTextureDestroyed(SurfaceTexture arg0) {
                    return false;
                }

                @Override
                public void onSurfaceTextureAvailable(SurfaceTexture surface, int arg1, int arg2) {
                    final MediaPlayer mediaPlayer = new MediaPlayer();
                    holder.vid_play.setTag(mediaPlayer);
                    new SetVideotask().execute(surface, vItem, mediaPlayer, holder.vid_play);                       
                }
            });
        }
    }

    return view;
}

class SetVideotask extends AsyncTask<Object, Integer, String>{

    @Override
    protected String doInBackground(Object... o) {
        // TODO Auto-generated method stub
        final SurfaceTexture s = (SurfaceTexture) o[0];
        final VoucherItem item = (VoucherItem) o[1];
        final MediaPlayer mediaPlayer = (MediaPlayer) o[2];
        final View v = (View) o[3];


        mediaPlayer.setSurface(new Surface(s));
        try {

            mediaPlayer.setDataSource(item.video);
            mediaPlayer.prepare();
            mediaPlayer.start();
            //I do this so there is a frame in the video to act as a preview
            Thread.sleep(100);
            mediaPlayer.pause();    
            mediaPlayer.setOnErrorListener(VoucherAdapter.this);                
        } catch (Exception e) {
            e.printStackTrace();
        }           

        return null;
    }       
}



static class ViewHolder {
    ImageView list_img;
    ImageView vid_play;
    TextureView video;
}


@Override
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
    return true;
}

      

+3


source to share


1 answer


This is because your instances AsyncTask

created in onSurfaceTextureAvailable

might not end sequentially, and on scrolling, the stream created for the new view

one might end before the stream processed view

(so the old data is loaded).

I managed to solve this case by creating a single thread pool that I terminate on scrolling.



Also, this is the final download question ListView

.

+1


source







All Articles