0

I have an app where I am using different players for playing different types of streams e.g. I am using MediaPlayer and YoutubePlayerSupportFragment through the YouTube player API. So for this I have made a separate controller for Play/Pause/etc, also a user may click a float button (which causes the player to shrink and drag). For this I am using a dialog (YouTube Player API doesn't allow any views on top of the player).

So the problem I am facing is this: while the Dialog is active (showing) no touch events pass through to the MainActivity. I overcame this issue by sending MotionEvents via dispatchTouchEvent() of the said Activity from the Dialog's dispatchTouchEvent(). It works well as I want it and I can now switch between different sections of app, but I can't get any Click Events on ListView and GridView only everything else works fine.

I checked the ListView's dispatchTouchEvent() and I am getting all of the MotionEvents.

Here's the code I use to send events to the MainActivity.

@Override
public boolean dispatchTouchEvent(MotionEvent event) {

    if (isPlayerMinimized) {
        if (playerDraggableView != null) {
            playerDraggableView.dispatchTouchEvent(event);
        }

        return ((MainActivity) mContext).dispatchTouchEvent(event);
    }
    else if (!onControlViews(event)) {
        detector.onTouchEvent(event);
    }

    return super.dispatchTouchEvent(event);
}

I can scroll the ListView and GridView but can't get OnItemClickListener or OnItemLongClickListener events to fire.

My question is, is this the correct/intended behavior? If so is there any way to send MotionEvents to the MainActivity. Or am I missing something? If that is the case then kindly point out.

I know there isn't enough code here to properly provide a solution but if I am missing something obvious here then please tell. Thanks!

Abbas
  • 3,529
  • 5
  • 36
  • 64

1 Answers1

0

It's not surprising that sending MotionEvents back to the MainActivity from a Dialog is not supported, that's definitely not the intended use of Dialogs.

It is possible to have multiple Fragments active within a single Activity at once, so there's no reason why you could not put a completely separate Fragment over the YouTubePlayerSupportFragment as transport controls or whatever you need. The trick is to place each Fragment in a container ViewGroup, such as a FrameLayout, and manage them that way.

You can't add another Fragment which overlaps, see edit below.

E.g.

SomeFragment fragment = SomeFragment.newInstance();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(containerId, fragment, "useful_tag_for_fragment");
fragmentTransaction.commitAllowingStateLoss();

Obviously make sure your transport (play, pause, stop controls) Fragment is above the YouTubePlayerSupportFragment in draw order or it will be occluded.

For the separate problem of communicating between Fragments and Activity objects, you can use Otto which is my personal favourite event bus.

EDIT

Though it's generally possible to overlay Fragments, YouTubePlayer specifically forbids this and throws a YouTubePlayer.ErrorReason.UNAUTHORIZED_OVERLAY error.

It does seem possible however to add an overlay over a YouTubePlayerView when used directly in an layout XML. The problem here is that you'll have to use an Activity which extends YouTubeBaseActivity, which doesn't support flexibility you're looking for, in particular for shrink and drag and swapping MediaPlayer wrapped Fragments, etc.

From what I can see there's no way around this, there's plenty of other people asking about this issue and nothing is coming up. At the end of the day, this code is closed source and YouTube obviously want to protect their branding.

r3flss ExlUtr
  • 720
  • 7
  • 17
  • Thanks for the response but like I said `YouTube Player` doesn't allow any views to be on top of itself. Except of course `Dialog`s and `DialogFragment`s. The player exits with an Overlay Error see this [link](https://developers.google.com/youtube/android/player/reference/com/google/android/youtube/player/YouTubePlayer.ErrorReason). – Abbas Aug 09 '16 at 12:04
  • I see, I haven't seen that before. Have you tried putting a `YouTubePlayerView` directly into your layout XML? I'm able to add any overlay over this, though I'm not using `YouTubePlayerSupportFragment`, my `Activity` extends `YouTubeBaseActivity` instead – r3flss ExlUtr Aug 09 '16 at 13:29
  • I haven't used `YouTubePlayerView` and I'd rather not. `YoutubePlayerSupportFragment` being a fragment provides the flexibility of easily switching between different players as well as provide a pretty useful backstack. So I'd rather keep using `YouTubePlayerSupportFragment` however if there is no other way out of this mess I might consider putting a `YoutubePlayerView` inside a fragment and see if that works. But for now I have 4 different players in my app and I can't just change the entire design. – Abbas Aug 09 '16 at 14:28
  • There is simply too much that depends on utilizing a `Fragment`'s life cycle and changing it will be a nightmare. – Abbas Aug 09 '16 at 14:30
  • Indeed, it's tough going. I can't find the source so it doesn't look like you could just fork it and disable the overlay error. You might have to go with the `YouTubePlayerView`. – r3flss ExlUtr Aug 09 '16 at 14:45