3

I am making an app where I have multiple texture views in a listview. I am using a list array adapter I always use so I know that I am properly recycling each list view item and that I am setting the correct url for the video in each texture view. However, If my list contains more than three videos, they start to "duplicate" themselves, meaning that the fourth list item renders, but video one renders in it instead of video four. Also, when I scroll down and back up, sometimes the video resource I have attacted to that texture view also changes like they are being "re-rendered" by the adapter. Should I not recycle the views? current relevant code:

   public class VideoListAdapter extends ArrayAdapter<videoitem>  {

   Context context;

 int phonewidth;
 int videoPlaying =0;

     List<MediaPlayer> playerList = new ArrayList(); 
     int pos;

    private final ImageDownloader mDownload = new ImageDownloader();
    public VideoListAdapter(Context context, int resourceId, List<videoitem> items) {
    super(context, resourceId, items);
     this.context = context;
   phonewidth = context.getResources().getDisplayMetrics().widthPixels;      
 }


   private class ViewHolder {


RelativeLayout wrapper;
InlineVideoPlayer videoPoster;
TextView numberOfLikes;
TextView numberOfDislikes;
ImageView UserIcon;
TextView userName;
TextView created;
ProgressBar p;
LinearLayout l;


   }
  public View getView(final int position, View convertView, ViewGroup parent) {
     ViewHolder holder = null;
 final videoitem rowItem = getItem(position);
     pos = position;

    LayoutInflater mInflater = (LayoutInflater)     context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);



   if (convertView == null) {
        convertView = mInflater.inflate(R.layout.videoitem,parent,  false);
           holder = new ViewHolder();


           holder.wrapper = (RelativeLayout) convertView.findViewById(R.id.videoholder);
           holder.l = (LinearLayout) convertView.findViewById(R.id.inlineVideoPlayer1);
      //       holder.videoPoster.setVideo("http//hub60.com/app/videos/" + rowItem.getVideo());
           holder.UserIcon = (ImageView) convertView.findViewById(R.id.imageView1);
           holder.numberOfDislikes = (TextView) convertView.findViewById(R.id.textView3);
           holder.numberOfLikes = (TextView) convertView.findViewById(R.id.ratinglikes);
           holder.created = (TextView) convertView.findViewById(R.id.textView2);
           holder.userName = (TextView) convertView.findViewById(R.id.textView1);

           holder.numberOfDislikes.setText(Integer.toString(position));
           holder.numberOfLikes.setText(rowItem.getLikes());
           holder.userName.setText(rowItem.getVideo());
           holder.created.setText(rowItem.getCreated());
           mDownload.download(rowItem.getIcon(), holder.UserIcon, null);
           holder.l.getLayoutParams().height = phonewidth;

        //   vid.setLayoutParams(new LayoutParams(
           //     LayoutParams.MATCH_PARENT,
      //          LayoutParams.MATCH_PARENT));


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

            holder.numberOfDislikes.setText(Integer.toString(position));
            holder.numberOfLikes.setText(rowItem.getLikes());
            holder.userName.setText(rowItem.getVideo());
            holder.created.setText(rowItem.getCreated());
            mDownload.download(rowItem.getIcon(), holder.UserIcon, null);

           convertView.setId(position);


   }



   InlineVideoPlayer vid = new InlineVideoPlayer(rowItem.getVideo(),context);
   ((LinearLayout) holder.l).addView(vid);
   return convertView;
}

in this particular case I took it out of the if/else deciding if the holder was empty and just added the view in question at the end. However I also had it in the if/else statement and am still experiencing the same behavior.

Custom texture view class

public class InlineVideoPlayer  extends TextureView implements SurfaceTextureListener{
     Context context;
     MediaPlayer mp;
      String url;
     Surface surface;
     SurfaceTexture s;

    public InlineVideoPlayer(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        this.context = context;
    }


    public InlineVideoPlayer(String ur,Context context)
    {
        super(context);
        this.setSurfaceTextureListener(this);
        this.url = ur;
        this.context = context;
    //  startVideo();
        //Log.d("url",this.url);
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int arg1, int arg2) {

        this.s = surface;

        Log.d("url",this.url);
        startVideo(surface);

    }
    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture arg0) {

        return true;
    }
    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture arg0, int arg1,int arg2) {
    }
    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture arg0) {
    }

    public void setVideo(String url)
    {
        this.url = url;

    }

    public void startVideo(SurfaceTexture t)
    {

            this.surface = new Surface(t);
            this.mp = new MediaPlayer();
            this.mp.setSurface(this.surface);
             try {
                 Uri uri = Uri.parse(this.url);
                 this.mp.setDataSource(this.context, uri);
                 this.mp.prepareAsync();
                 this.mp.setOnPreparedListener(new OnPreparedListener() {
                     public void onPrepared(MediaPlayer mp) {

                        mp.setLooping(true);
                        mp.seekTo(2000);
                        mp.start();
                //      mp.pause();

                    }
                });



                } catch (IllegalArgumentException e1) {
                    e1.printStackTrace();
                } catch (SecurityException e1) {
                    e1.printStackTrace();
                } catch (IllegalStateException e1) {
                    e1.printStackTrace();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }  
               try {

                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }
                try {

                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }




    }

}

thank you in advance

Megaman
  • 149
  • 12
Dnaso
  • 1,335
  • 4
  • 22
  • 48

1 Answers1

0

the answer is: this is not possible, The developer must work with reusable cells and insert a movie player at the rightindex for the appropiate cell and when a cell is created null out the media player currently playing

Dnaso
  • 1,335
  • 4
  • 22
  • 48
  • Did you find out a way to show a list of videos inside ListView? Even with simple list using reusable cells I am seeing a lot of glitches. Are you using any hacks or tricks to avoid such problems? Could you show code for your solution? – Piotr Feb 24 '14 at 22:29
  • use surfaceview. After searching I found that surface view is on the same compositing layer as all other views and has the ability to be translated like all other views except texture view & video view – Dnaso Feb 25 '14 at 19:11
  • weird, I am testing TextureView right now and I don't see glitches mentioned by you. VideoView was working awful though. Could you post your SurfaceView-based source code? Thanks – Piotr Feb 25 '14 at 19:41
  • you will see it once you use 5 + – Dnaso Feb 25 '14 at 20:51
  • I am using around 10. I see that it takes some time to replace one video to another, but it always renders correct video. – Piotr Feb 25 '14 at 21:22
  • nice.. what phone are you using? – Dnaso Feb 25 '14 at 21:25
  • basically I am targeting >=4.0. And I am using Motorola Droid Mini and HTC One for testing – Piotr Feb 25 '14 at 22:05
  • @Piotr I can able to load multiple video in Listview.As you mention that it's take time to replace one video to another. Do you have any solution of this issue? – Dhaval Khant Sep 17 '14 at 07:36
  • @DhavalKhant I am using placeholder image and I replace it with movie only if it's fully loaded – Piotr Sep 17 '14 at 18:04
  • @Piotr i am doing same thing. but didn't get movie is fully loaded. – Dhaval Khant Sep 18 '14 at 04:08
  • Use your own custom video player that inits depending on the cell you are using.You should never have more than one video at a time @Piotr – Dnaso Sep 18 '14 at 19:33
  • @Piotr could you please give a link to your adapter class to help me and other who are really struggling with this. – Amanni Sep 19 '14 at 18:50
  • @Dnaso, the specs say just otherwise "Unlike SurfaceView, TextureView does not create a separate window but behaves as a regular View. This key difference allows a TextureView to be moved, transformed, animated, etc. For instance, you can make a TextureView semi-translucent by calling myView.setAlpha(0.5f)." – Lassi Kinnunen Apr 25 '16 at 14:49