Android自定义view,实现多画面播放器,可以通过设置参数来设置画面个数,双击某个画面可以全屏显示这个画面,并暂停其他画面的播放,可以通过左滑或右滑来播放上一个或下一个视频
项目地址:http://download.csdn.net/download/weixin_40391500/10137528
private static final int VIDEO_VIEW_COUNT = 16;
private Context mContext;
private VideoView mVideoView[]; //视频画面,最多9画面
private int mVideoMode = 2; //显示模式,1表示单画面,2表示4画面,3表示9画面,4表示16画面
private int mActiveIndex = 0; //焦点画面
public boolean mShowMax = false; //是否最大化显示
private int mChannelCount = 4; //通道数目,由实际的设备决定
private int mBeginIndex = 0; //开始显示的索引
private ArrayList<String> urlList = new ArrayList<>();//播放地址
public VideoGroupLayout(Context context) {
super(context);
initLayout(context);
}
public VideoGroupLayout(Context context, AttributeSet atrb) {
super(context, atrb);
initLayout(context);
}
public VideoGroupLayout(Context context, AttributeSet atrb, int defStyle) {
super(context, atrb, defStyle);
initLayout(context);
}
private void initLayout(Context context) {
this.mContext = context;
createVideoView();
setLongClickable(true);
}
public void createVideoView() {
int i = 0;
VideoPlayListener playListener = new VideoPlayListener();
playListener.onBeginPlay(this);
this.mVideoView = new VideoView[VIDEO_VIEW_COUNT];
for (i = 0; i < VIDEO_VIEW_COUNT; ++i) {
this.mVideoView[i] = new VideoView(this.mContext, i);
this.mVideoView[i].setPlayerListener(playListener);
this.mVideoView[i].setVideoListener();
this.mVideoView[i].setId(1000 + i);
this.mVideoView[i].setVisibility(View.VISIBLE);
this.mVideoView[i].setClickable(false);
this.mVideoView[i].setFocusable(false);
this.mVideoView[i].setDrawFocus(true);
this.mVideoView[i].setFocusableInTouchMode(false);
this.mVideoView[i].setHapticFeedbackEnabled(false);
addView(this.mVideoView[i]);
}
mActiveIndex = 0;
mBeginIndex = 0;
this.mVideoView[mActiveIndex].setIsFocus(true);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (changed) {
postDelayed(new ResizeVideoView(), 100L);
}
}
public void switchActiveView(Integer index) {
if (mActiveIndex != index) {
mVideoView[mActiveIndex].setIsFocus(false);
mVideoView[mActiveIndex].invalidate();
mActiveIndex = index;
mVideoView[mActiveIndex].setIsFocus(true);
mVideoView[mActiveIndex].invalidate();
}
}
public void moveNextView() {
//4画面也可以左移,右移
if (this.mShowMax) {
int nNextIndex = mActiveIndex + 1;
if (nNextIndex >= mChannelCount) {
nNextIndex = 0;
}
switchActiveView(nNextIndex);
updateBeginIndex();
moveVideoView();
} else {
//车辆只有单通道,只显示1画面,不显示4画面
//车辆有2-4通道,只显示4画面
//车辆有5-8通道,只显示4画面
//1和4画面时,也可以上一组和下一组
int viewCount = mVideoMode * mVideoMode;
if (this.mChannelCount > viewCount) {
int nBegin = this.mBeginIndex + viewCount;
if (nBegin >= this.mChannelCount) {
nBegin = 0;
}
switchActiveView(nBegin);
updateBeginIndex();
moveVideoView();
}
}
}
public void movePrevView() {
//4画面也可以左移,右移
if (this.mShowMax) {
int nNextIndex = mActiveIndex - 1;
if (nNextIndex < 0) {
nNextIndex = mChannelCount - 1;
}
switchActiveView(nNextIndex);
updateBeginIndex();
moveVideoView();
} else {
//车辆只有单通道,只显示1画面,不显示4画面
//车辆有2-4通道,只显示4画面
//车辆有5-8通道,只显示4画面
//1和4画面时,也可以上一组和下一组
int viewCount = mVideoMode * mVideoMode;
if (this.mChannelCount > viewCount) {
int nBegin = this.mBeginIndex - viewCount;
if (nBegin < 0) {
nBegin = this.mChannelCount / viewCount * viewCount;
if ((this.mChannelCount % viewCount) == 0) {
nBegin -= 1;
}
}
switchActiveView(nBegin);
updateBeginIndex();
moveVideoView();
}
}
}
protected void updateBeginIndex() {
int viewCount = mVideoMode * mVideoMode;
if (this.mActiveIndex >= this.mBeginIndex && this.mActiveIndex < (this.mBeginIndex + viewCount)) {
return;
}
int nBegin = 0;
while (true) {
int nEnd = nBegin + viewCount;
if (this.mActiveIndex >= nBegin && this.mActiveIndex < nEnd) {
this.mBeginIndex = nBegin;
break;
}
nBegin += viewCount;
}
}
public void moveVideoView() {
int nWidth = getWidth();
if (nWidth > 0) {
nWidth -= 2;
}
int nHeight = getHeight();
if (nHeight > 0) {
nHeight -= 2;
}
if (this.mShowMax) {
for (int i = 0; i < VIDEO_VIEW_COUNT; ++i) {
if (i != mActiveIndex) {
this.mVideoView[i].setCurIndex(this.mVideoView[i].getCurrentPosition());
this.mVideoView[i].pause();
this.mVideoView[i].setVisibility(View.GONE);
}
}
LayoutParams layoutParams = new LayoutParams(nWidth, nHeight);
layoutParams.leftMargin = 1;
layoutParams.topMargin = 1;
this.mVideoView[mActiveIndex].setVisibility(View.VISIBLE);
this.mVideoView[mActiveIndex].setLayoutParams(layoutParams);
this.mVideoView[mActiveIndex].invalidate();
this.mVideoView[mActiveIndex].start();
} else {
int nPreWidth = nWidth / mVideoMode;
int nPreHeight = nHeight / mVideoMode;
int begIndex = this.mBeginIndex;
int totalCount = mVideoMode * mVideoMode;
int i = 0;
int j = 0;
for (i = 0; i < mVideoMode; ++i) {
for (j = 0; j < mVideoMode; ++j) {
int index = (i * mVideoMode + j + begIndex) % VIDEO_VIEW_COUNT;
LayoutParams layoutParams = new LayoutParams(nPreWidth, nPreHeight);
layoutParams.topMargin = 1 * i + nPreHeight * i;
layoutParams.leftMargin = 1 * j + nPreWidth * j;
this.mVideoView[index].setVisibility(View.VISIBLE);
this.mVideoView[index].setLayoutParams(layoutParams);
this.mVideoView[index].setLongClickable(true);
this.mVideoView[index].invalidate();
if (index != mActiveIndex){
this.mVideoView[index].seekTo(this.mVideoView[index].getCurIndex());
}
this.mVideoView[index].start();
}
}
//将其它Video 隐藏
int endIndex = begIndex + totalCount;
if (endIndex >= VIDEO_VIEW_COUNT) {
int temp = endIndex % VIDEO_VIEW_COUNT;
for (i = temp; i < begIndex; ++i) {
this.mVideoView[i].setCurIndex(this.mVideoView[i].getCurrentPosition());
this.mVideoView[i].pause();
this.mVideoView[i].setVisibility(View.GONE);
this.mVideoView[i].setLongClickable(false);
}
} else {
for (i = 0; i < begIndex; ++i) {
this.mVideoView[i].setCurIndex(this.mVideoView[i].getCurrentPosition());
this.mVideoView[i].pause();
this.mVideoView[i].setVisibility(View.GONE);
this.mVideoView[i].setLongClickable(false);
}
for (i = endIndex; i < VIDEO_VIEW_COUNT; ++i) {
this.mVideoView[i].setCurIndex(this.mVideoView[i].getCurrentPosition());
this.mVideoView[i].pause();
this.mVideoView[i].setVisibility(View.GONE);
this.mVideoView[i].setLongClickable(false);
}
}
}
}
final class ResizeVideoView implements Runnable {
public final void run() {
moveVideoView();
}
}
/*
* 停止所有视频
*/
public void stopAllAV() {
for (int i = 0; i < VIDEO_VIEW_COUNT; ++i) {
this.mVideoView[i].setCurIndex(0);
mVideoView[i].stopPlayback();
}
}
/*
* 设置预览此设备的视频
*/
public void setViewDev(ArrayList<String> list) {
urlList = list;
if (urlList == null) return;
int i = 0;
for (i = 0; i < urlList.size(); ++i) {
mVideoView[i].setVideoPath(urlList.get(i));
}
for (i = urlList.size() - 1; i < VIDEO_VIEW_COUNT; ++i) {
//setting play name
}
//切换画面数目模式
boolean resize = false;
this.mChannelCount = urlList.size();
if (this.mChannelCount == 1) {
if (this.mVideoMode != 1 || this.mBeginIndex != 0) {
this.mVideoMode = 1;
this.mBeginIndex = 0;
resize = true;
switchActiveView(this.mBeginIndex);
}
} else {
if (this.mBeginIndex != 0) {
this.mBeginIndex = 0;
resize = true;
switchActiveView(this.mBeginIndex);
}
if (this.mVideoMode == 1) {
this.mVideoMode = 2;
resize = true;
}
if (this.mShowMax) {
this.mShowMax = false;
resize = true;
}
}
if (resize) {
moveVideoView();
}
}
/*
* 播放视频
*/
public void playView() {
//当前画面模式为4画面,则同时开始4个画面的视频
//如果为1画面,则开启1个画面的视频
if (this.mShowMax || this.mVideoMode == 1) {
if (this.mVideoView[mActiveIndex].isPlaying()) {
this.mVideoView[mActiveIndex].setCurIndex(this.mVideoView[mActiveIndex].getCurrentPosition());
this.mVideoView[this.mActiveIndex].pause();
} else {
this.mVideoView[mActiveIndex].seekTo(this.mVideoView[mActiveIndex].getCurIndex());
this.mVideoView[this.mActiveIndex].start();
}
} else {
int begIndex = this.mBeginIndex;
int totalCount = this.mBeginIndex + mVideoMode * mVideoMode;
if (isViewing()) {
for (int i = begIndex; i < totalCount && i < urlList.size(); ++i) {
this.mVideoView[i].stopPlayback();
}
} else {
for (int i = begIndex; i < totalCount && i < urlList.size(); ++i) {
this.mVideoView[i].seekTo(this.mVideoView[i].getCurIndex());
this.mVideoView[i].start();
//监听播放完成,重置进度值
this.mVideoView[i].setOnCompletionListener(this);
}
}
}
}
@Override
public void onCompletion(MediaPlayer mp) {
for (int i = 0; i < VIDEO_VIEW_COUNT; ++i) {
if (mp.getDuration() == this.mVideoView[i].getDuration()){
this.mVideoView[i].setCurIndex(0);
System.out.println("============="+i);
}
}
}
/*
* 获取是否当前的画面模式处理播放状态
*/
public boolean isViewing() {
if (this.mShowMax || this.mVideoMode == 1) {
return this.mVideoView[this.mActiveIndex].isPlaying();
} else {
int begIndex = this.mBeginIndex;
int totalCount = begIndex + mVideoMode * mVideoMode;
boolean allViewing = true;
for (int i = begIndex; i < totalCount && i < urlList.size(); ++i) {
if (!this.mVideoView[i].isPlaying()) {
allViewing = false;
}
}
return allViewing;
}
}
项目地址:http://download.csdn.net/download/weixin_40391500/10137528