如何在 VideoView 中使用手势滑动功能播放视频

Posted

技术标签:

【中文标题】如何在 VideoView 中使用手势滑动功能播放视频【英文标题】:How to Play Video using Gesture Swipe function in VideoView 【发布时间】:2016-08-16 09:10:55 【问题描述】:

我有VideoView,我想使用手势滑动功能播放视频。当用户从右向左滑动播放下一个视频以及从左向右滑动播放上一个视频时。 它工作正常,但是当我当时滑动数组列表的最后一项时,我的应用程序崩溃了(array index out of bound)。

这是我的代码:

class ActivitySwipeDetector implements View.OnTouchListener 

        static final String logTag = "ActivitySwipeDetector";
        private Activity activity;
        static final int MIN_DISTANCE = 100;
        private float downX, downY, upX, upY;

        public ActivitySwipeDetector(Activity activity) 
            this.activity = activity;
        

        public void onRightSwipe() 
            LOGE(logTag, "RightToLeftSwipe!");
            if (mProgressDialog == null) 
                mProgressDialog = ViewUtils.createProgressDialog(mActivity);
                mProgressDialog.show();
             else 
                mProgressDialog.show();
            
            i++;
            if (i < mArrayList.size()) 
                LOGD("Index:: :: :: ::", String.valueOf(i));
                Uri videoUri = Uri.parse(mArrayList.get(i));
                videoview.setVideoURI(videoUri);
                videoview.start();
             else 
                mProgressDialog.dismiss();
            
        

        public void onLeftSwipe() 
            LOGE(logTag, "LeftToRightSwipe!");
            if (mProgressDialog == null) 
                mProgressDialog = ViewUtils.createProgressDialog(mActivity);
                mProgressDialog.show();
             else 
                mProgressDialog.show();
            
            i--;
            if (i > mArrayList.size()) 
                Uri videoUri = Uri.parse(mArrayList.get(i));
                videoview.setVideoURI(videoUri);
                videoview.start();
             else 
                mProgressDialog.dismiss();
            
        

        public void onDownSwipe() 
            LOGE(logTag, "onTopToBottomSwipe!");
        

        public void onUpSwipe() 
            LOGE(logTag, "onBottomToTopSwipe!");
            finish();
        

        public boolean onTouch(View v, MotionEvent event) 
            switch (event.getAction()) 
                case MotionEvent.ACTION_DOWN: 
                    downX = event.getX();
                    downY = event.getY();
                    return true;
                
                case MotionEvent.ACTION_UP: 
                    upX = event.getX();
                    upY = event.getY();

                    float deltaX = downX - upX;
                    float deltaY = downY - upY;

                    // swipe horizontal?
                    if (Math.abs(deltaX) > Math.abs(deltaY)) 
                        if (Math.abs(deltaX) > MIN_DISTANCE) 
                            // left or right
                            if (deltaX > 0) 
                                this.onRightSwipe();
                                return true;
                            
                            if (deltaX < 0) 
                                this.onLeftSwipe();
                                return true;
                            
                         else 
                            LOGE(logTag, "Horizontal Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
                            return false; // We don't consume the event
                        
                    
                    // swipe vertical?
                    else 
                        if (Math.abs(deltaY) > MIN_DISTANCE) 
                            // top or down
                            if (deltaY < 0) 
                                this.onDownSwipe();
                                return true;
                            
                            if (deltaY > 0) 
                                this.onUpSwipe();
                                return true;
                            
                         else 
                            LOGE(logTag, "Vertical Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
                            return false; // We don't consume the event
                        
                    

                    return true;
                
            
            return false;
        
    

【问题讨论】:

任何人有解决这个问题的想法? 【参考方案1】:

试试下面的代码。

class ActivitySwipeDetector implements View.OnTouchListener 

static final String logTag = "ActivitySwipeDetector";
private Activity activity;
static final int MIN_DISTANCE = 100;
private float downX, downY, upX, upY;

public ActivitySwipeDetector(Activity activity) 
    this.activity = activity;


public void onRightSwipe() 
    LOGE(logTag, "RightToLeftSwipe!");
    if (mProgressDialog == null) 
        mProgressDialog = ViewUtils.createProgressDialog(mActivity);
        mProgressDialog.show();
     else 
        mProgressDialog.show();
    
    i++;
    if(i>=mArrayList.size())
        i=0;
    if (i < mArrayList.size()) 
        LOGD("Index:: :: :: ::", String.valueOf(i));
        Uri videoUri = Uri.parse(mArrayList.get(i));
        videoview.setVideoURI(videoUri);
        videoview.start();
     else 
        mProgressDialog.dismiss();
    


public void onLeftSwipe() 
    LOGE(logTag, "LeftToRightSwipe!");
    if (mProgressDialog == null) 
        mProgressDialog = ViewUtils.createProgressDialog(mActivity);
        mProgressDialog.show();
     else 
        mProgressDialog.show();
    
    i--;
    if(i < 0)
        i= mArrayList.size()-1;

    if (i > mArrayList.size()) 
        Uri videoUri = Uri.parse(mArrayList.get(i));
        videoview.setVideoURI(videoUri);
        videoview.start();
     else 
        mProgressDialog.dismiss();
    


public void onDownSwipe() 
    LOGE(logTag, "onTopToBottomSwipe!");


public void onUpSwipe() 
    LOGE(logTag, "onBottomToTopSwipe!");
    finish();


public boolean onTouch(View v, MotionEvent event) 
    switch (event.getAction()) 
        case MotionEvent.ACTION_DOWN: 
            downX = event.getX();
            downY = event.getY();
            return true;
        
        case MotionEvent.ACTION_UP: 
            upX = event.getX();
            upY = event.getY();

            float deltaX = downX - upX;
            float deltaY = downY - upY;

            // swipe horizontal?
            if (Math.abs(deltaX) > Math.abs(deltaY)) 
                if (Math.abs(deltaX) > MIN_DISTANCE) 
                    // left or right
                    if (deltaX > 0) 
                        this.onRightSwipe();
                        return true;
                    
                    if (deltaX < 0) 
                        this.onLeftSwipe();
                        return true;
                    
                 else 
                    LOGE(logTag, "Horizontal Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
                    return false; // We don't consume the event
                
            
            // swipe vertical?
            else 
                if (Math.abs(deltaY) > MIN_DISTANCE) 
                    // top or down
                    if (deltaY < 0) 
                        this.onDownSwipe();
                        return true;
                    
                    if (deltaY > 0) 
                        this.onUpSwipe();
                        return true;
                    
                 else 
                    LOGE(logTag, "Vertical Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
                    return false; // We don't consume the event
                
            

            return true;
        
    
    return false;


【讨论】:

还是出现异常? 检查两个方向都工作或只有一个方向不工作。 完美,现在你可以检查你的值是否等于0,然后在if语句之前分配i =mArrayList.length(),再加一个if 你能简单描述一下吗? 让我们continue this discussion in chat。

以上是关于如何在 VideoView 中使用手势滑动功能播放视频的主要内容,如果未能解决你的问题,请参考以下文章

使用VideoView自定义一个播放器控件

水平 RecyclerView 中的 VideoView 在滑动时显示墙纸

如何在videoview中播放流视频

SurfaceView/VideoView

无法在android的videoview中播放来自url的视频如何在videoview中播放来自URL的视频?

Android多媒体功能开发——使用VideoView控件播放视频