Android自定义view,实现多画面播放器

Android自定义view,实现多画面播放器,可以通过设置参数来设置画面个数,双击某个画面可以全屏显示这个画面,并暂停其他画面的播放,可以通过左滑或右滑来播放上一个或下一个视频
项目地址:http://download.csdn.net/download/weixin_40391500/10137528
4画面
双击全屏画面

    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

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值