17

我正在嘗試使用藤或Instagram應用等視頻實現列表。當列表項顯示或完全可見時視頻播放的位置以及視頻在列表項隱藏時暫停。我正在使用帶媒體播放器的textureview從url播放視頻,並將它作爲清單項目添加到recyclerview中。以下是我的代碼。在recyclerview中使用紋理視圖播放視頻

VideosAdapter類:

public class VideosAdapter extends RecyclerView.Adapter<VideosAdapter.ViewHolder> { 

Context context; 
private ArrayList<String> urls; 

public static class ViewHolder extends RecyclerView.ViewHolder { 

    public LinearLayout layout; 
    public TextView textView; 

    public ViewHolder(View v) { 
     super(v); 
     layout = (LinearLayout) v.findViewById(R.id.linearLayout); 
     textView = (TextView) v.findViewById(R.id.textView); 
    } 
} 

public VideosAdapter(Context context, ArrayList<String> urls) { 
    this.context = context; 
    this.urls = urls; 
} 

// Create new views (invoked by the layout manager) 
@Override 
public VideosAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    // create a new view 
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_main, parent, false); 
    ViewHolder viewHolder = new ViewHolder(v); 
    return viewHolder; 
} 

// Replace the contents of a view (invoked by the layout manager) 
@Override 
public void onBindViewHolder(ViewHolder holder, int position) { 

    String url = urls.get(position); 
    holder.textView.setText(url); 
    playVideo(holder, url); 
} 

@Override 
public int getItemCount() { 
    return urls.size(); 
} 

private void playVideo(ViewHolder holder, String url) 
{ 
    final CustomVideoPlayer vid = new CustomVideoPlayer(String.valueOf(url), context); 
    holder.layout.addView(vid); 
    holder.layout.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      vid.changePlayState(); 
     } 
    }); 
} 
} 

CustomVideoPlayer類:

public class CustomVideoPlayer extends TextureView implements TextureView.SurfaceTextureListener 
{ 

Context context; 
String url; 
MediaPlayer mp; 
Surface surface; 
SurfaceTexture s; 

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

public CustomVideoPlayer(String ur, Context context) 
{ 
    super(context); 
    this.setSurfaceTextureListener(this); 
    this.url = ur; 
    this.context = context; 

} 

@Override 
public void onSurfaceTextureAvailable(final 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(url); 
     this.mp.prepareAsync(); 

     this.mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 
      public void onPrepared(MediaPlayer mp) { 

       mp.setLooping(true); 
       mp.start(); 

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


} 

public void changePlayState() 
{ 
    if(this.mp.isPlaying()) 
     this.mp.pause(); 
    else 
     this.mp.start(); 
} 
} 

當我運行這段代碼,中間有多個問題。

1)前兩個項目/視頻緩衝區並播放正常。但是當我滾動它不加載第三個視頻,第一個視頻也從列表中刪除。

2)在滾動視頻/列表項目上,爲已緩衝的項目再次開始緩衝。

3)在快速滾動列表變得太滯後,並卡住和崩潰。

附加是我在列表滾動和視頻播放時獲得的logcat圖像。

enter image description here

任何人都可以指導我這個?什麼是正確的方式來創建像藤蔓應用程序的列表?

+0

有上同時視頻的數量依賴於設備的限制。確保在開始播放之前停止播放前一個視頻。 'M'版本計劃添加一個API,它會告訴你什麼是限制 - http://developer.android.com/preview/api-overview.html#video。 – fadden

+0

感謝您的回覆。我已經添加了3個網址來玩。但沒有開始播放並且評論了這一行mp.start();從startVideo(表面)方法。當我滾動時,我得到的問題listview卡住5-6秒。爲什麼我得到此如果此問題與播放或一次播放多個視頻有關,因爲現在我只準備所有視頻,但尚未開始播放。 –

回答

26

我能夠通過首先從url下載視頻,然後使用自定義播放器來實現。這裏是我的情況下,如何做,如果別人需要的:

1)獲取所有網址的需要播放

2)開始從本地存儲的URL下載視頻(隊列),並保持在偏好的標誌(即一個視頻已經下載或不)

3)指定URL到適配器,其中初始化視頻播放器控制器,其處理視頻播放

4)設置addOnScrollListener檢查哪個位置/視頻是當前可見的對象,並檢查視頻是否已經下載,如果是,請播放。

以下是完整代碼:

MainActivity

public class MainActivity extends ActionBarActivity implements IVideoDownloadListener { 

private static String TAG = "MainActivity"; 

private Context context; 
private RecyclerView mRecyclerView; 
private ProgressBar progressBar; 
private VideosAdapter mAdapter; 
private RecyclerView.LayoutManager mLayoutManager; 
private ArrayList<Video> urls; 
VideosDownloader videosDownloader; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    context = MainActivity.this; 
    mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view); 
    progressBar = (ProgressBar) findViewById(R.id.progressBar); 
    urls = new ArrayList<Video>(); 
    mRecyclerView.setHasFixedSize(true); 
    mLayoutManager = new LinearLayoutManager(this); 
    mRecyclerView.setLayoutManager(mLayoutManager); 
    mAdapter = new VideosAdapter(MainActivity.this, urls); 
    mRecyclerView.setAdapter(mAdapter); 

    videosDownloader = new VideosDownloader(context); 
    videosDownloader.setOnVideoDownloadListener(this); 

    if(Utils.hasConnection(context)) 
    { 
     getVideoUrls(); 

     mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { 
      @Override 
      public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
       super.onScrolled(recyclerView, dx, dy); 
      } 

      @Override 
      public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 
       super.onScrollStateChanged(recyclerView, newState); 

       if (newState == RecyclerView.SCROLL_STATE_IDLE) { 

        LinearLayoutManager layoutManager = ((LinearLayoutManager) recyclerView.getLayoutManager()); 
        int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition(); 
        int findFirstCompletelyVisibleItemPosition = layoutManager.findFirstCompletelyVisibleItemPosition(); 

        Video video; 
        if (urls != null && urls.size() > 0) 
        { 
         if (findFirstCompletelyVisibleItemPosition >= 0) { 
          video = urls.get(findFirstCompletelyVisibleItemPosition); 
          mAdapter.videoPlayerController.setcurrentPositionOfItemToPlay(findFirstCompletelyVisibleItemPosition); 
          mAdapter.videoPlayerController.handlePlayBack(video); 
         } 
         else 
         { 
          video = urls.get(firstVisiblePosition); 
          mAdapter.videoPlayerController.setcurrentPositionOfItemToPlay(firstVisiblePosition); 
          mAdapter.videoPlayerController.handlePlayBack(video); 
         } 
        } 
       } 
      } 
     }); 
    } 
    else 
     Toast.makeText(context, "No internet available", Toast.LENGTH_LONG).show(); 
} 

@Override 
public void onVideoDownloaded(Video video) { 
    mAdapter.videoPlayerController.handlePlayBack(video); 
} 

private void getVideoUrls() 
{ 
    Video video1 = new Video("0", "1", "http://techslides.com/demos/sample-videos/small.mp4"); 
    urls.add(video1); 
    Video video2 = new Video("1", "2", "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4"); 
    urls.add(video2); 
    Video video3 = new Video("2", "3", "http://sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4"); 
    urls.add(video3); 
    Video video4 = new Video("3", "4", "http://dev.exiv2.org/attachments/341/video-2012-07-05-02-29-27.mp4"); 
    urls.add(video4); 
    Video video5 = new Video("4", "5", "http://techslides.com/demos/sample-videos/small.mp4"); 
    urls.add(video5); 
    Video video6 = new Video("5", "6", "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4"); 
    urls.add(video6); 
    Video video7 = new Video("6", "7", "http://sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4"); 
    urls.add(video7); 

    mAdapter.notifyDataSetChanged(); 
    progressBar.setVisibility(View.GONE); 
    videosDownloader.startVideosDownloading(urls); 
} 
} 

VideosAdapter

public class VideosAdapter extends RecyclerView.Adapter<VideosAdapter.ViewHolder> { 

private static String TAG = "VideosAdapter"; 

Context context; 
private ArrayList<Video> urls; 
public VideoPlayerController videoPlayerController; 

public static class ViewHolder extends RecyclerView.ViewHolder { 

    public TextView textView; 
    public ProgressBar progressBar; 
    public RelativeLayout layout; 

    public ViewHolder(View v) { 
     super(v); 
     layout = (RelativeLayout) v.findViewById(R.id.layout); 
     textView = (TextView) v.findViewById(R.id.textView); 
     progressBar = (ProgressBar) v.findViewById(R.id.progressBar); 

    } 
} 

public VideosAdapter(Context context, final ArrayList<Video> urls) { 

    this.context = context; 
    this.urls = urls; 
    videoPlayerController = new VideoPlayerController(context); 
} 

// Create new views (invoked by the layout manager) 
@Override 
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    // create a new view 
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_main, parent, false); 

    Configuration configuration = context.getResources().getConfiguration(); 
    int screenWidthDp = configuration.screenWidthDp; //The current width of the available screen space, in dp units, corresponding to screen width resource qualifier. 
    int smallestScreenWidthDp = configuration.smallestScreenWidthDp; //The smallest screen size an application will see in normal operation, corresponding to smallest screen width resource qualifier. 

    ViewHolder viewHolder = new ViewHolder(v); 

    int screenWidthPixels = Utils.convertDpToPixel(screenWidthDp, context); 
    RelativeLayout.LayoutParams rel_btn = new RelativeLayout.LayoutParams(
      ViewGroup.LayoutParams.MATCH_PARENT, screenWidthPixels); 
    viewHolder.layout.setLayoutParams(rel_btn); 

    return viewHolder; 
} 

// Replace the contents of a view (invoked by the layout manager) 
@Override 
public void onBindViewHolder(final ViewHolder holder, int position) { 

    Video video = urls.get(position); 
    holder.textView.setText("Video " + video.getId()); 

    final VideoPlayer videoPlayer = new VideoPlayer(context); 
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT); 
    videoPlayer.setLayoutParams(params); 

    holder.layout.addView(videoPlayer); 
    videoPlayerController.loadVideo(video, videoPlayer, holder.progressBar); 
    videoPlayer.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      videoPlayer.changePlayState(); 
     } 
    }); 
} 

@Override 
public void onViewRecycled(ViewHolder holder) { 
    super.onViewRecycled(holder); 
    Log.d(TAG, "onViewRecycledCalled"); 
    holder.layout.removeAllViews(); 

} 

@Override 
public int getItemCount() { 
    return urls.size(); 
} 

} 

VideosDownloader

public class VideosDownloader { 

private static String TAG = "VideosDownloader"; 

Context context; 
FileCache fileCache; 
IVideoDownloadListener iVideoDownloadListener; 

public VideosDownloader(Context context) { 
    this.context = context; 
    fileCache = new FileCache(context); 
} 

///////////////////////////////////////////////////////////////// 
// Start downloading all videos from given urls 

public void startVideosDownloading(final ArrayList<Video> videosList) 
{ 
    Thread thread = new Thread(new Runnable() { 
     @Override 
     public void run() 
     { 
      for(int i=0; i<videosList.size(); i++) 
      { 
       final Video video = videosList.get(i); 
       String id = video.getId(); 
       String url = video.getUrl(); 

       String isVideoDownloaded = Utils.readPreferences(context, video.getUrl(), "false"); 
       boolean isVideoAvailable = Boolean.valueOf(isVideoDownloaded); 
       if(!isVideoAvailable) 
       { 
        //Download video from url 
        String downloadedPath = downloadVideo(url); 
        //Log.i(TAG, "Vides downloaded at: " + downloadedPath); 
        Activity activity = (Activity) context; 
        activity.runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          Utils.savePreferences(context, video.getUrl(), "true"); 
          iVideoDownloadListener.onVideoDownloaded(video); 
         } 
        }); 
       } 

      } 
     } 
    }); 
    thread.start(); 
} 

///////////////////////////////////////////////////////////////// 

private String downloadVideo(String urlStr) 
{ 
    URL url = null; 
    File file = null; 
    try 
    { 
     file = fileCache.getFile(urlStr); 
     url = new URL(urlStr); 
     long startTime = System.currentTimeMillis(); 
     URLConnection ucon = null; 
     ucon = url.openConnection(); 
     InputStream is = ucon.getInputStream(); 
     BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5); 
     FileOutputStream outStream = new FileOutputStream(file); 
     byte[] buff = new byte[5 * 1024]; 

     //Read bytes (and store them) until there is nothing more to read(-1) 
     int len; 
     while ((len = inStream.read(buff)) != -1) { 
      outStream.write(buff, 0, len); 
     } 

     //clean up 
     outStream.flush(); 
     outStream.close(); 
     inStream.close(); 

    } 
    catch (MalformedURLException e) { 
     e.printStackTrace(); 
    } 
    catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return file.getAbsolutePath(); 
} 


public void setOnVideoDownloadListener(IVideoDownloadListener iVideoDownloadListener) { 
    this.iVideoDownloadListener = iVideoDownloadListener; 
} 
} 

VideoPlayerController

public class VideoPlayerController { 

private static String TAG = "VideoPlayerController"; 

Context context; 
FileCache fileCache; 
int currentPositionOfItemToPlay = 0; 
Video currentPlayingVideo; 

private Map<String, VideoPlayer> videos = Collections.synchronizedMap(new WeakHashMap<String, VideoPlayer>()); 
private Map<String, ProgressBar> videosSpinner = Collections.synchronizedMap(new WeakHashMap<String, ProgressBar>()); 

public VideoPlayerController(Context context) { 

    this.context = context; 
    fileCache = new FileCache(context); 
} 

public void loadVideo(Video video, VideoPlayer videoPlayer, ProgressBar progressBar) { 

    //Add video to map 
    videos.put(video.getIndexPosition(), videoPlayer); 
    videosSpinner.put(video.getIndexPosition(), progressBar); 

    handlePlayBack(video); 
} 

//This method would check two things 
//First if video is downloaded or its local path exist 
//Second if the videoplayer of this video is currently showing in the list or visible 

public void handlePlayBack(Video video) 
{ 
    //Check if video is available 
    if(isVideoDownloaded(video)) 
    { 

     // then check if it is currently at a visible or playable position in the listview 
     if(isVideoVisible(video)) 
     { 
      //IF yes then playvideo 
      playVideo(video); 
     } 
    } 
} 

private void playVideo(final Video video) 
{ 
    //Before playing it check if this video is already playing 

    if(currentPlayingVideo != video) 
    { 
     //Start playing new url 
     if(videos.containsKey(video.getIndexPosition())) 
     { 
      final VideoPlayer videoPlayer2 = videos.get(video.getIndexPosition()); 
      String localPath = fileCache.getFile(video.getUrl()).getAbsolutePath(); 
      if(!videoPlayer2.isLoaded) 
      { 
       videoPlayer2.loadVideo(localPath, video); 
       videoPlayer2.setOnVideoPreparedListener(new IVideoPreparedListener() { 
        @Override 
        public void onVideoPrepared(Video mVideo) { 

         //Pause current playing video if any 
         if(video.getIndexPosition() == mVideo.getIndexPosition()) 
         { 
          if(currentPlayingVideo!=null) 
          { 
           VideoPlayer videoPlayer1 = videos.get(currentPlayingVideo.getIndexPosition()); 
           videoPlayer1.pausePlay(); 
          } 
          videoPlayer2.mp.start(); 
          currentPlayingVideo = mVideo; 
         } 


        } 
       }); 
      } 
      else 
      { 
       //Pause current playing video if any 
       if(currentPlayingVideo!=null) 
       { 
        VideoPlayer videoPlayer1 = videos.get(currentPlayingVideo.getIndexPosition()); 
        videoPlayer1.pausePlay(); 
       } 

       boolean isStarted = videoPlayer2.startPlay(); 
       { 
        //Log.i(TAG, "Started playing Video Index: " + video.getIndexPosition()); 
        //Log.i(TAG, "Started playing Video: " + video.getUrl()); 
       } 
       currentPlayingVideo = video; 
      } 
     } 
    } 
    else 
    { 
     //Log.i(TAG, "Already playing Video: " + video.getUrl()); 
    } 

} 

private boolean isVideoVisible(Video video) { 

    //To check if the video is visible in the listview or it is currently at a playable position 
    //we need the position of this video in listview and current scroll position of the listview 
    int positionOfVideo = Integer.valueOf(video.getIndexPosition()); 

    if(currentPositionOfItemToPlay == positionOfVideo) 
     return true; 

    return false; 
} 

private boolean isVideoDownloaded(Video video) { 

    String isVideoDownloaded = Utils.readPreferences(context, video.getUrl(), "false"); 
    boolean isVideoAvailable = Boolean.valueOf(isVideoDownloaded); 
    if(isVideoAvailable) 
    { 
     //If video is downloaded then hide its progress 
     hideProgressSpinner(video); 
     return true; 
    } 

    showProgressSpinner(video); 
    return false; 
} 

private void showProgressSpinner(Video video) { 
    ProgressBar progressBar = videosSpinner.get(video.getIndexPosition()); 
    if(progressBar!=null) 
     progressBar.setVisibility(View.VISIBLE); 
} 

private void hideProgressSpinner(Video video) { 

    ProgressBar progressBar = videosSpinner.get(video.getIndexPosition()); 
    if(progressBar!=null && progressBar.isShown()) 
    { 
     progressBar.setVisibility(View.GONE); 
     Log.i(TAG, "ProgressSpinner Hided Index: " + video.getIndexPosition()); 
    } 
} 

public void setcurrentPositionOfItemToPlay(int mCurrentPositionOfItemToPlay) { 
    currentPositionOfItemToPlay = mCurrentPositionOfItemToPlay; 
} 
} 

的VideoPlayer

public class VideoPlayer extends TextureView implements TextureView.SurfaceTextureListener { 

private static String TAG = "VideoPlayer"; 

/**This flag determines that if current VideoPlayer object is first item of the list if it is first item of list*/ 
boolean isFirstListItem; 

boolean isLoaded; 
boolean isMpPrepared; 

IVideoPreparedListener iVideoPreparedListener; 

Video video; 
String url; 
MediaPlayer mp; 
Surface surface; 
SurfaceTexture s; 

public VideoPlayer(Context context) { 
    super(context); 
} 

public VideoPlayer(Context context, AttributeSet attrs) 
{ 
    super(context, attrs); 
} 

public void loadVideo(String localPath, Video video) { 

    this.url = localPath; 
    this.video = video; 
    isLoaded = true; 

    if (this.isAvailable()) { 
     prepareVideo(getSurfaceTexture()); 
    } 

    setSurfaceTextureListener(this); 
} 

@Override 
public void onSurfaceTextureAvailable(final SurfaceTexture surface, int width, int height) { 
    isMpPrepared = false; 
    prepareVideo(surface); 
} 

@Override 
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 

} 

@Override 
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 

    if(mp!=null) 
    { 
     mp.stop(); 
     mp.reset(); 
     mp.release(); 
     mp = null; 
    } 

    return false; 
} 

@Override 
public void onSurfaceTextureUpdated(SurfaceTexture surface) { 
} 

public void prepareVideo(SurfaceTexture t) 
{ 

    this.surface = new Surface(t); 
    mp = new MediaPlayer(); 
    mp.setSurface(this.surface); 

    try { 
     mp.setDataSource(url); 
     mp.prepareAsync(); 

     mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 
      public void onPrepared(MediaPlayer mp) { 
       isMpPrepared = true; 
       mp.setLooping(true); 
       iVideoPreparedListener.onVideoPrepared(video); 
      } 


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

} 

@Override 
protected void onAttachedToWindow() { 
    super.onAttachedToWindow(); 
} 

@Override 
protected void onVisibilityChanged(View changedView, int visibility) { 
    super.onVisibilityChanged(changedView, visibility); 
} 

public boolean startPlay() 
{ 
    if(mp!=null) 
     if(!mp.isPlaying()) 
     { 
      mp.start(); 
      return true; 
     } 

    return false; 
} 

public void pausePlay() 
{ 
    if(mp!=null) 
     mp.pause(); 
} 

public void stopPlay() 
{ 
    if(mp!=null) 
     mp.stop(); 
} 

public void changePlayState() 
{ 
    if(mp!=null) 
    { 
     if(mp.isPlaying()) 
      mp.pause(); 
     else 
      mp.start(); 
    } 

} 

public void setOnVideoPreparedListener(IVideoPreparedListener iVideoPreparedListener) { 
    this.iVideoPreparedListener = iVideoPreparedListener; 
} 
} 

IVideoDownloadListener

public interface IVideoDownloadListener { 
public void onVideoDownloaded(Video video); 
} 

IVideoPreparedListener

public interface IVideoPreparedListener { 

public void onVideoPrepared(Video video); 
} 
+1

yo thx分享! – sirvon

+1

嗨@Nouman Bhatti。你可以分享這個代碼作爲一個單一的項目。這對我完全有幫助。謝謝。 –

+0

你可以分享你的完整的源代碼在工作模式或寄給我[email protected] ..謝謝 – MPG

4

爲什麼不在自己的佈局文件「view_main」中添加自定義視頻視圖。 檢查視頻視圖的可見性並僅在視圖可見時播放。

public static boolean isViewVisible(View subView, View parentView) { 
    Rect scrollBounds = new Rect(); 
    parentView.getHitRect(scrollBounds); 
    if (subView.getLocalVisibleRect(scrollBounds)) { 
     return true; 
    } 
    return false; 
} 

檢查visiblity的代碼。當滾動狀態空閒時,在滾動狀態改變的監聽器中調用它。

此外,您還必須使用AsyncTask下載視頻,但一次只下載一個視頻,否則可能會發生內存不足錯誤。

+0

無法使用視頻視圖,因爲它不適用於滾動。你也可以詳細說明在哪裏調用上面的方法來獲取可見的listview項目? –

+0

視頻視圖我的意思是你的自定義視圖。 –

+0

您必須重寫列表的onScrollListener並獲取頂部可見項。順便使用Recycler視圖或List視圖? –

4

您應該通過在後端下載視頻並從本地內存一次播放一個視頻來保持視頻緩存,以保持列表滾動順暢。