真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網站制作重慶分公司

詳解Android視頻滾動列表(偷懶型)

公司的項目需要一個視頻的滾動列表。

站在用戶的角度思考問題,與客戶深入溝通,找到向陽網站設計與向陽網站推廣的解決方案,憑借多年的經驗,讓設計與互聯(lián)網技術結合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都網站建設、成都網站制作、企業(yè)官網、英文網站、手機端網站、網站推廣、域名與空間、雅安服務器托管、企業(yè)郵箱。業(yè)務覆蓋向陽地區(qū)。

搜了些文章比較常見的是根據列表項的可視百分比來判斷的。實現起來略復雜。

這里想了一個在要求不高的情況下,實現相對簡便的方法:根據列表滾動時可見的第一個列表項的位置來播放和暫停對應列表項內的視頻。

它的效果大致是這樣的:

詳解Android 視頻滾動列表(偷懶型) 

以下是它的實現。

首先當然是建立列表。

這部分就直接用ListView吧,列表的具體的實現就不貼了。大致就是長這樣的一個列表:

詳解Android 視頻滾動列表(偷懶型) 

接下來就是添加播放器。

這里需要注意的是,在ListView里不能使用我們常用的那種VideoView?;赟urfaceView的VideoView由于沒有同步緩沖區(qū),它不能在ListView中正常顯示。(顯然SurfaceView+MediaPlayer的形式也不太適合了)我們需要基于TextureView的視頻播放器。

這里偷個懶,就直接用 PLDroidPlayer這個庫中的PLVideoTextureView了

在列表的Adapter中的添加播放器。

Adapter的布局:

<?xml version="1.0" encoding="utf-8"?>

  
    
      
      
    
    
  

Adapter部分代碼:

package net.codepig.playerlist.adapers;

import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.pili.pldroid.player.AVOptions;
import com.pili.pldroid.player.PLMediaPlayer;
import com.pili.pldroid.player.widget.PLVideoTextureView;

import net.codepig.playerlist.R;
import net.codepig.playerlist.beans.VideoInfo;
import net.codepig.playerlist.deviceInfo;

import java.util.List;

/**
 * 視頻單元頁面
 * Created by QZD on 2017/11/13.
 */

public class PlayerAdapter extends BaseAdapter{
  private Context _context;
  private Activity mainActivity;
  private List myVideoData;
  private LayoutInflater inflater;
  private ViewHolder hodler = null;
  private PLMediaPlayer mPlayer=null;
//  private PLVideoTextureView myVideoView;
  private int _id;
  private String _name;
  private String _url="";

  private final String TAG="LOGCAT";

  public PlayerAdapter(Context context, List data) {
    super();
    _context = context;
    mainActivity=(Activity) context;
    myVideoData = data;
    inflater = LayoutInflater.from(context);
  }

  @Override
  public View getView(final int postion, View convertView, ViewGroup parent) {
    hodler = new ViewHolder();
    convertView = inflater.inflate(R.layout.player_adapter_l, null);
    hodler.videoName_t = convertView.findViewById(R.id.videoName_t);
    hodler.videoTable = convertView.findViewById(R.id.videoTable);
    hodler.myVideoView = convertView.findViewById(R.id.myVideoView);
    convertView.setTag(hodler);

    hodler.videoTable.getLayoutParams().width= deviceInfo._screenWidth;
    hodler.videoTable.getLayoutParams().height=deviceInfo._screenHeight;
//    Log.d(TAG,"screenSize:"+deviceInfo._screenWidth+"-"+deviceInfo._screenHeight);

    VideoInfo _vInfo=myVideoData.get(postion);
    _name=_vInfo.get_name();
    hodler.videoName_t.setText(_vInfo.get_name());
    _id=_vInfo.get_id();
    _url=_vInfo.get_url();
    if(!_url.equals("")) {
      setVideo(_url);
    }

    return convertView;
  }

  /**
   * 初始化播放器
   * @param url
   */
  private void setVideo(String url){
    int codec = mainActivity.getIntent().getIntExtra("mediaCodec", AVOptions.MEDIA_CODEC_AUTO);
    AVOptions options = new AVOptions();
    options.setInteger(AVOptions.KEY_PREPARE_TIMEOUT, 10 * 1000);
    options.setInteger(AVOptions.KEY_MEDIACODEC, codec);
    hodler.myVideoView.setAVOptions(options);
    hodler.myVideoView.setVideoPath(url);
    hodler.myVideoView.start();

    hodler.myVideoView.setOnErrorListener(new PLMediaPlayer.OnErrorListener(){
      @Override
      public boolean onError(PLMediaPlayer mp, int errorCode) {
        Log.d(TAG,"errorCode:"+errorCode);
        return true;
      }
    });
    hodler.myVideoView.setOnCompletionListener(new PLMediaPlayer.OnCompletionListener() {
      @Override
      public void onCompletion(PLMediaPlayer mp) {
//        Log.d(TAG, "player onCompletion:"+videoDuration/1000+"-"+_curTime/1000);
        hodler.myVideoView.seekTo(0);
        hodler.myVideoView.start();
      }
    });
    hodler.myVideoView.setOnPreparedListener(new PLMediaPlayer.OnPreparedListener() {
      @Override
      public void onPrepared(PLMediaPlayer mediaPlayer, int percent) {
        Log.d(TAG, "player onPrepared");
        if(mPlayer==null){
          mPlayer=mediaPlayer;
        }
        //播放
        if(hodler.myVideoView!=null){
          hodler.myVideoView.start();
        }else{
          Log.d(TAG, _name+"no myVideoView");
        }
      }
    });
    hodler.myVideoView.setOnBufferingUpdateListener(new PLMediaPlayer.OnBufferingUpdateListener() {
      @Override
      public void onBufferingUpdate(PLMediaPlayer mp, int percent) {
        try {
          int _pec = hodler.myVideoView.getBufferPercentage();//百分比到99就停,進度條會留空
          if (_pec == 99) {
            _pec = 100;
          }
        }catch (Exception e){
          Log.d(TAG,"percentage error:"+e.toString());
        }
      }
    });
    hodler.myVideoView.setOnVideoSizeChangedListener(new PLMediaPlayer.OnVideoSizeChangedListener() {
      @Override
      public void onVideoSizeChanged(PLMediaPlayer plMediaPlayer, int width, int height) {
        Log.d(TAG,"VideoSize:"+width+"_"+height);
      }
    });
  }

  @Override
  public int getCount() {
    if (myVideoData != null) {
      return myVideoData.size();
    } else {
      return 0;
    }
  }

  @Override
  public Object getItem(int position) {
    return myVideoData.get(position);
  }

  @Override
  public long getItemId(int postion) {
    // TODO Auto-generated method stub
    return postion;
  }

  public static class ViewHolder {
    public TextView videoName_t;
    public RelativeLayout videoTable;
    public PLVideoTextureView myVideoView;
  }
}

添加完播放器大致長這樣:

詳解Android 視頻滾動列表(偷懶型) 

接下來就是重點了,要根據列表的滾動來播放和暫停視頻。

這里根據當前滾動的位置來進行判斷。

首先添加滾動監(jiān)聽:

    myVideoList.setAdapter(playerAdapter);
    myVideoList.setOnScrollListener(new AbsListView.OnScrollListener() {
      @Override
      public void onScrollStateChanged(AbsListView view, int scrollState) {
//        Log.d(TAG,"onScrollStateChanged:"+scrollState);
        //SCROLL_STATE_FLING = 滾動中;SCROLL_STATE_IDLE = 結束滾動;SCROLL_STATE_TOUCH_SCROLL = 開始滾動;
        if(scrollState==SCROLL_STATE_IDLE){
          Log.d(TAG,"FirstVisiblePosition:"+myVideoList.getFirstVisiblePosition());
          View v0=myVideoList.getChildAt(0);
          if(v0!=null){
            int scrollTop=v0.getTop();
            Log.d(TAG,"scroll top:"+scrollTop);
          }
        }
      }

      @Override
      public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
      }
    });

這里通過getFirstVisiblePosition()獲得可見的第一個元素,并使用getTop()獲得該元素的偏移量。

接下來增加對元素內視頻的操作,這里通過更新列表的數據來實現。

修改一下上面的監(jiān)聽,判斷當前第二個可見item的位置,當到達指定位置時將播放標識置為true。原先播放中的item的播放標識置為false。
然后更新數據。

     myVideoList.setOnScrollListener(new AbsListView.OnScrollListener() {
      @Override
      public void onScrollStateChanged(AbsListView view, int scrollState) {
        //SCROLL_STATE_FLING = 滾動中;SCROLL_STATE_IDLE = 結束滾動;SCROLL_STATE_TOUCH_SCROLL = 開始滾動;
        if(scrollState==SCROLL_STATE_IDLE){
          int _index=myVideoList.getFirstVisiblePosition()+1;
          View v1=myVideoList.getChildAt(1);//取可見元素的第二個
          if(v1!=null){
            int scrollTop=v1.getTop();
            if(scrollTop<200){
              if(_oldItem!=_index) {
                _infoList.get(_index).set_playing(true);
                _infoList.get(_oldItem).set_playing(false);
                _oldItem=_index;
                playerAdapter.notifyDataSetChanged();
              }
            }
//            Log.d(TAG,"scroll top:"+scrollTop);
          }
        }
      }

      @Override
      public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
      }
    });

這個的位置判斷上直接寫死了200像素,作為一個DEMO,位置判斷的數值上不是很講究。這個其實應該根據滾動方向和item的高度來計算的。

在Adapter的getView()方法中根據_playing的狀態(tài)播放或停止視頻:(停止的時候要記得釋放掉播放器資源哦,不然列表中這么多視頻的內存占用是很可怕的哦。)

  @Override
  public View getView(final int postion, View convertView, ViewGroup parent) {
    hodler = new ViewHolder();
    convertView = inflater.inflate(R.layout.player_adapter_l, null);
    hodler.videoName_t = convertView.findViewById(R.id.videoName_t);
    hodler.videoTable = convertView.findViewById(R.id.videoTable);
    hodler.myVideoView = convertView.findViewById(R.id.myVideoView);
    convertView.setTag(hodler);

    hodler.videoTable.getLayoutParams().width= deviceInfo._screenWidth;
    hodler.videoTable.getLayoutParams().height=deviceInfo._screenHeight;
    Log.d(TAG,"screenSize:"+deviceInfo._screenWidth+"-"+deviceInfo._screenHeight);

    VideoInfo _vInfo=myVideoData.get(postion);
    _name=_vInfo.get_name();
    hodler.videoName_t.setText(_vInfo.get_name());
    _id=_vInfo.get_id();
    _url=_vInfo.get_url();
    if(!_url.equals("")) {
    //視頻的播放和停止
      if(_vInfo.get_playing()){
        setVideo(_url);
      }else{
        if(hodler.myVideoView!=null) {
          if (hodler.myVideoView.isPlaying()) {
            hodler.myVideoView.stopPlayback();
            hodler.myVideoView.releaseSurfactexture();
          }
        }
      }
    }
    return convertView;
  }

嗯,完工。

改天再整列表的可視百分比判斷。

相關github項目地址:https://github.com/codeqian/playerlist

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。


網頁題目:詳解Android視頻滾動列表(偷懶型)
文章出自:http://weahome.cn/article/jdhisd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部