64

I have written these lines of code:

 mVideoView = (VideoView) findViewById(R.id.video_view);
    mVideoView.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.v("LOG_TAG, click");
        }
    });

However, when I run my application, the click event is never called.

So I wonder, is it impossible to register an OnClickListener on a VideoView? And, if so, why is that the case?

Robert Massaioli
  • 13,379
  • 7
  • 57
  • 73
Fabian
  • 973
  • 1
  • 11
  • 14

11 Answers11

86

use VideoView.setOnTouchListener(..) it works for VideoView

Andro Selva
  • 53,910
  • 52
  • 193
  • 240
newdev
  • 1,363
  • 1
  • 12
  • 18
18

Here's how I solved the pause/play of VideoViews using onTouch:

// Class variables
private boolean bVideoIsBeingTouched = false;
private Handler mHandler = new Handler();

vvVideo.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
    if (!bVideoIsBeingTouched) {
        bVideoIsBeingTouched = true;
    if (vvVideo.isPlaying()) {
        vvVideo.pause();
    } else {
        vvVideo.resume();
    }
    mHandler.postDelayed(new Runnable() {
        public void run() {
            bVideoIsBeingTouched = false;
        }
        }, 100);
    }
    return true;
    }
});
Dan
  • 724
  • 1
  • 9
  • 19
  • 2
    For those where `resume()` does not work; here is solution [Stack](http://www.google.co.in/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCkQFjAA&url=http%3A%2F%2Fstackoverflow.com%2Fquestions%2F11960730%2Fresume-playing-videoview-from-onresume&ei=JmbjUqmGK8P9rAe29IDYBA&usg=AFQjCNHWIPXnoKBCfV4ctFukFPDXYl303g&sig2=NJyXl7J9j8FA3AOBEmIXow&bvm=bv.59930103,d.bmk) – BlueSword Jan 25 '14 at 07:31
  • 1
    What is the purpose of 'bVideoIsBeingTouched' variable? As far as I can see you are only rewriting it but you don't use it. – Jerry Aug 16 '17 at 09:34
  • using `bVideoIsBeingTouched` is horrible workaround, you should detect `MotionEvent.ACTION_UP` – AndrewBloom Feb 26 '20 at 15:53
16

I know this is old but I used this:

    mVideoView.setOnTouchListener(new View.OnTouchListener()
    {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            Log.i(TAG, "Video 1 clicked, starting playback");

            return false;
        }
    });
nawlrus
  • 777
  • 1
  • 13
  • 27
15

I know this is and old question, but here is what I did:

Since setOnClickListener is not been triggered, I created my own class which extends VideoView

public class VideoViewCustom extends VideoView{

and Overrided the onTouchEvent

@Override
public boolean onTouchEvent(MotionEvent ev) {

    if(ev.getAction() == MotionEvent.ACTION_DOWN){
        Log.d(TAG, "ACTION_DOWN");
    }

    return super.onTouchEvent(ev);
}

and now I can get the onClick event with the MotionEvent.

Hope this helps someone!

Larry Mustaine
  • 169
  • 1
  • 5
  • 8
    In general, touch events for "click" should only be consumed on ACTION_UP, not ACTION_DOWN to allow the user to express intent to click. That's why other events like ACTION_CANCEL exist. The user begins to press, then moves their pointer outside of the bounds of the view. – Dallas Sep 01 '13 at 22:01
  • Dallas is right, it should be ACTION_UP instead of ACTION_DOWN – Larry Mustaine Feb 06 '14 at 15:56
  • 4
    I just came across this problem and I agree that ACTION_UP is usually better practice but in this case the VideoView only seems to provide ACTION_DOWN! – Gyan aka Gary Buyn Mar 26 '15 at 22:21
  • I found the same, it only uses down – Clive Jefferies Dec 05 '16 at 16:59
2

This is probably long overdue, nonetheless of some help to those who may run into a similar problem. The way I got around this problem was by laying a transparent image view right on top of the video view, then listening to onClick events on the image view, and doing whatever it was I wanted to do with the video view afterwards.

Michael M
  • 161
  • 2
  • 7
2

I realize this is an old question but thought I'd chime in with an easy workaround. I can't answer why this doesn't work - seems like a big oversight in my opinion. But an easy workaround is to place your VideoView as the sole View inside a FrameLayout, and set an OnClickListener on the layout. Not ideal, but it works.

mszaro
  • 1,362
  • 1
  • 13
  • 25
1

You can well use a button which is transparent on the video view if you want a specific part of the video on touch to do something.

Mouna
  • 11
  • 1
1

The VideoView is a wrapper containing MediaPlayer and SurfaceView. You can interact with through MediaController or writing your own SurfaceView and implement onClick events.

Oriol Roma
  • 329
  • 1
  • 5
  • 9
nahwarang
  • 654
  • 5
  • 9
  • Interactions between a VideoView and a MediaController are quite limited. For example, during a tap action, VideoView will only check if MediaController is showing and show/hide it accordingly. Although you can surely hack in these APIs, that is not what those APIs are expected. – Henry Aug 18 '21 at 15:42
1

You can solve this issue through cover layout. I used the linearlayout.

            <LinearLayout
                android:id="@+id/video1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center">
                <VideoView
                    android:id="@+id/video2"
                    android:layout_width="370dp"
                    android:layout_height="180dp"
                    android:layout_gravity="center"
                    app:elevation = "0dp"
                    android:background="@mipmap/video"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    android:visibility="visible"
                    />

            </LinearLayout>

and try it in source file.

video1.setOnClickListener {
                if(Video.isPlaying) {
                    Video.pause()
                }
                else {
                    Video.start()
                }
}
Dev Solution
  • 144
  • 2
  • 10
0

You might try Gesture Overlay View

You should be able to overlay this view on top of another view in order to get touch events.

Hope this helps!

Codeman
  • 12,157
  • 10
  • 53
  • 91
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – sashoalm Feb 05 '15 at 14:37
  • d'oh. I was a newbie when I wrote this one :) – Codeman Feb 05 '15 at 18:13
-3

It is possible I have did this with onSetClickListener. And Here's a code for your help:

mVideoView.setOnClickListener(new View.OnClickListener() {
    @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            //Here you put a condition for playing a video when you click on your video view.//
            if(my_video.isPressed())
            {   
                my_video.start();
            } else {
                Toast.makeText(getApplicationContext(), 
                    "Not able to run This Video!", 
                    Toast.LENGTH_LONG).show();
            }
        }
    });
Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
user1300242
  • 49
  • 2
  • 9
  • 3
    Man, this is exactly what the OP says he's doing! The point is that it does not work when video is playing. – Alex Nov 06 '12 at 18:15