I have a Listview which displays videos in some rows so the user can watch the video via the listview using TextureView. So far the videos load and play correctly but they seem to show up in the wrong order at times while scrolling. I believe this is due to the adapter recycling views but I am not sure how to fix this.
here is my implementation
There is the getView which handles rendering the views and then there is an AsyncTask started by the getView to setup 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;
}