5

I've a layout that I play a video there and I want to handle onClick on this player. In my linear layout I've the fragment of youtube as suggested in their api:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment        
        android:name="com.google.android.youtube.player.YouTubePlayerFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/youtubePlayerFragment"/>
</LinearLayout>

Then I access this fragment in my Activity:

mYouTubePlayerFragment = (YouTubePlayerFragment) getFragmentManager().findFragmentById(R.id.youtubePlayerFragment);

and I initialize it:

    mYouTubePlayerFragment.initialize(CategoriesTabsData.DEVELOPER_KEY, new com.google.android.youtube.player.YouTubePlayer.OnInitializedListener() {
        @Override
        public void onInitializationSuccess(com.google.android.youtube.player.YouTubePlayer.Provider provider, com.google.android.youtube.player.YouTubePlayer youTubePlayer, boolean b) {
             // loading the video                
        }

        @Override
        public void onInitializationFailure(com.google.android.youtube.player.YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {

        }
    });

I want to print "click" to Log.d when the player is clicked. So when a video is played and its player is clicked/touched, I want to print "click" to the log

I'm trying to handle a click on the player (I get the youtubeplayer object in onInitializationSuccess) but I don't succeed.

I tried this:

    mYouTubePlayerFragment.getView().setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("youtube", "click");
        }
    });

but it doesn't reach onClick. Then I tried to create MyYouTubePlayerFragment that extends YouTubePlayerFragment and implements View.OnClickListener so I set the fragment in my xml with the appropriate name (com.mypackagename.MyYouTubePlayerFragment) and set the type of mYouTubePlayerFragment to be MyYouTubePlayerFragment but it didn't reach onClick.

How can I "catch" the click on the video?

Maor Cohen
  • 936
  • 2
  • 18
  • 33
  • here is the answer https://stackoverflow.com/questions/4415528/how-to-pass-the-onclick-event-to-its-parent-on-android – Viktor Yakunin Jan 15 '18 at 17:30
  • when I add dispatchTouchEvent, it doesn't reach this code when the player is full screen and I touch it. it recognized my click only when the player is small size – Maor Cohen Jan 15 '18 at 17:45
  • this means that player starts fullscreen activity with the player or it is different view – Viktor Yakunin Jan 15 '18 at 18:30
  • the player starts full screen and it is inside a fragment with the name: android:name="com.google.android.youtube.player.YouTubePlayerFragment". So should I start it NOT as full screen? and how can I know that the click is on the player and not the layout below? – Maor Cohen Jan 15 '18 at 19:23
  • Did you try adding on click listener in LinearLayout ? – nimi0112 Jan 16 '18 at 10:11
  • sure but it doesn't reach it unfortunately. pity that I don't find an option to know if the play\pause button is visible because it can be used as an alternative to know if the user clicked on the player. (when the button becomes from visible to invisible or the contrary) – Maor Cohen Jan 16 '18 at 11:40
  • @ViktorYakunin Can you post your comment (dispach listener) as the answer? So I can give you the bounty because it seems that this is the best answer and that it can solve the issue :) – Maor Cohen Jan 20 '18 at 20:52
  • Use Layout Inspector to figure out the view hierarchy. You're most likely setting the listener on some parent of the actual youtube player view. Since youtube player view itself captures click events your listener is never invoked. – Eugen Pechanec Jan 22 '18 at 10:15
  • @MaorCohen Did you get any solution for this. – Rajeev Shetty Jul 29 '21 at 10:52
  • sorry but not having this code anymore – Maor Cohen Jan 05 '22 at 20:42

4 Answers4

4

So to listen to click events in parent view you should pass click event from child to parent. In google documentation there are few ways to do that, and there are helper methods for higher level views like Activity, Fragment, ViewGroup, ViewParent:

There are some other methods that you should be aware of, which are not part of the View class, but can directly impact the way you're able to handle events. So, when managing more complex events inside a layout, consider these other methods:

Activity.dispatchTouchEvent(MotionEvent) - This allows your Activity to intercept all touch events before they are dispatched to the window.

ViewGroup.onInterceptTouchEvent(MotionEvent) - This allows a ViewGroup to watch events as they are dispatched to child Views.

ViewParent.requestDisallowInterceptTouchEvent(boolean) - Call this upon a parent View to indicate that it should not intercept touch events with onInterceptTouchEvent(MotionEvent).

Viktor Yakunin
  • 2,927
  • 3
  • 24
  • 39
2

I think you should extend YouTubeSupportFragment and add to your YoutubePlayer (inside onInitializationSuccess method) YouTubePlayer.PlaybackEventListener.

Probably you are interested in onPaused() and onPlaying() methods.

Example:

@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
    youTubePlayer = player;
    if (!wasRestored) {
        youTubePlayer.setPlaybackEventListener(new YouTubePlayer.PlaybackEventListener() {
            @Override
            public void onPlaying() {

            }

            @Override
            public void onPaused() {

            }

            @Override
            public void onStopped() {

            }

            @Override
            public void onBuffering(boolean b) {

            }

            @Override
            public void onSeekTo(int i) {

            }
        });
        youTubePlayer.cueVideo(currentVideoID, 0);
    }
}
YMY
  • 678
  • 9
  • 17
  • 1
    no because I want to recognize any click on the player (not only stop\play). So even if the user presses on the player and it doesn't stop the video, I want to recognize it. – Maor Cohen Jan 15 '18 at 17:34
1

I kinda ran into something like this and ended up creating a wrapper view to intercept the touch events.

Perhaps you could do something like this:

public class YourYouTubePlayerSupportFragment extends YouTubePlayerSupportFragment {

@Override
public View onCreateView(LayoutInflater layoutInflater, ViewGroup viewGroup, Bundle bundle) {
    YouTubePlayerView youTubePlayerView = (YouTubePlayerView) super.onCreateView(layoutInflater, viewGroup, bundle);
    final FrameLayout wrapper = new FrameLayout(getActivity()) {

        private GestureDetector gestureDetector;
        private GestureDetector.SimpleOnGestureListener gestureListener = new GestureDetector.SimpleOnGestureListener() {
                  @Override
                  public boolean onSingleTapConfirmed(MotionEvent e) {
                        //do what you need to here
                        return super.onSingleTapConfirmed(e);
                  }
             };

        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            if (gestureDetector == null) {
                gestureDetector = new GestureDetector(getContext(), gestureListener);
            }
            return gestureDetector.onTouchEvent(ev);
        }
    };

    FrameLayout.LayoutParams viewLp = new FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
    wrapper.addView(youTubePlayerView, viewLp);
    return wrapper;
}

}
Jagoan Neon
  • 1,072
  • 11
  • 13
  • it causes illegalstateexception with the reason that I should call removeview from the view's parent but view.getParent() is null – Maor Cohen Jan 22 '18 at 08:27
  • `viewGroup` is parent view of the fragment view. Don't use it in scope of the fragment. I don't see a return statement, can you modify it so it compiles? – Eugen Pechanec Jan 22 '18 at 10:18
  • Kinda made it in a rush, and forgot to clean up some code. I just edited it. Check it out, if it doesn't work I'll probably try it in a new project – Jagoan Neon Jan 22 '18 at 14:25
0

Try to extend YouTubeSupportFragment and override onCreateView method like this:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = super.onCreateView(inflater, container, savedInstanceState);

    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("youtube", "click");
        }
    });

    return view;
}
y.allam
  • 1,446
  • 13
  • 24