Несколько TextureViews в списке отображают неправильное видео

Я делаю приложение, в котором у меня есть несколько представлений текстуры в виде списка. Я использую адаптер массива списков, который я всегда использую, поэтому я знаю, что я правильно перерабатываю каждый элемент представления списка и что я устанавливаю правильный URL-адрес для видео в каждом представлении текстуры. Однако, если мой список содержит более трех видео, они начинают «дублировать» себя, что означает, что рендерится четвертый элемент списка, но рендерится в нем первое видео вместо четвертого. Кроме того, когда я прокручиваю вниз и возвращаюсь назад, иногда видеоресурс, который я привязал к этому представлению текстуры, также изменяется, как будто он «повторно визуализируется» адаптером. Должен ли я не перерабатывать просмотры? текущий соответствующий код:

   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;
}

в этом конкретном случае я убрал его из if/else, решив, был ли держатель пуст, и просто добавил рассматриваемое представление в конце. Однако у меня также было это в выражении if/else, и я все еще испытываю такое же поведение.

Пользовательский класс просмотра текстуры

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();
                }




    }

}

заранее спасибо


person Dnaso    schedule 04.01.2014    source источник


Ответы (1)


ответ: это невозможно, разработчик должен работать с повторно используемыми ячейками и вставлять проигрыватель фильмов в правый индекс для соответствующей ячейки, а когда ячейка создается, обнулять медиаплеер, воспроизводимый в данный момент.

person Dnaso    schedule 28.01.2014
comment
Вы нашли способ показать список видео внутри ListView? Даже с простым списком, использующим повторно используемые ячейки, я вижу много сбоев. Используете ли вы какие-либо хаки или приемы, чтобы избежать таких проблем? Не могли бы вы показать код для вашего решения? - person Piotr; 25.02.2014
comment
используйте вид на поверхность. После поиска я обнаружил, что представление поверхности находится на том же композитном слое, что и все другие представления, и имеет возможность переводиться, как и все другие представления, кроме просмотра текстуры и просмотра видео. - person Dnaso; 25.02.2014
comment
странно, я сейчас тестирую TextureView и не вижу упомянутых вами глюков. Однако VideoView работал ужасно. Не могли бы вы опубликовать исходный код на основе SurfaceView? Спасибо - person Piotr; 25.02.2014
comment
ты увидишь это, как только воспользуешься 5+ - person Dnaso; 26.02.2014
comment
Я использую около 10. Я вижу, что замена одного видео на другое занимает некоторое время, но всегда воспроизводит правильное видео. - person Piotr; 26.02.2014
comment
хорошо .. какой телефон вы используете? - person Dnaso; 26.02.2014
comment
в основном я ориентируюсь на ›=4.0. И я использую Motorola Droid Mini и HTC One для тестирования. - person Piotr; 26.02.2014
comment
@Piotr Я могу загрузить несколько видео в Listview. Как вы упомянули, замена одного видео другим занимает время. У вас есть решение этой проблемы? - person Dhaval Khant; 17.09.2014
comment
@DhavalKhant Я использую изображение-заполнитель и заменяю его фильмом, только если он полностью загружен. - person Piotr; 17.09.2014
comment
@Piotr, я делаю то же самое. но не получил фильм полностью загружен. - person Dhaval Khant; 18.09.2014
comment
Используйте свой собственный видеоплеер, который запускается в зависимости от используемой вами ячейки. У вас никогда не должно быть более одного видео одновременно @Piotr - person Dnaso; 18.09.2014
comment
@Piotr, не могли бы вы дать ссылку на свой класс адаптера, чтобы помочь мне и другим, кто действительно борется с этим. - person Amanni; 19.09.2014
comment
@Dnaso, спецификации говорят об обратном. В отличие от SurfaceView, TextureView не создает отдельное окно, а ведет себя как обычное представление. Это ключевое отличие позволяет перемещать, преобразовывать, анимировать и т. д. TextureView. Например, вы можете сделать TextureView полупрозрачным, вызвав myView.setAlpha(0.5f). - person Lassi Kinnunen; 25.04.2016