There have been a lot of discussions about how to position a MediaController
and most answers are to use the setAnchorView
-Method. At the first glance this solution seems to work but in my case it doesn't.
According to this Post setAnchorView
only acts as a reference for initial positioning of the MediaController
, but actually creates a new floating Window
on top.
So what I want is a MediaController
that is really bound to a parent View
(e.g. VideoView).
For example if you have a LinearLayout
within a ScrollView
and you have to scroll down to your VideoView
where the MediaController
is attached to, the MediaController
should really be attached to this VideoView
so that the MediaController
scrolls along with the VideoView
.
Another Use-Case where this problem accurs is discussed here, where the MediaController
is used within a ViewPager
.
So how to achieve such a behavior for a MediaController
?
I ended up by doing a dirty hack... i just manually attached the view to my videoView
to achieve the wanted behavior:
public void onPrepared(MediaPlayer mp) {
MediaController mc = new MediaController(videoView.getContext(), false);
// set correct height
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) videoView.getLayoutParams();
params.height = mp.getVideoHeight();
videoView.setLayoutParams(params);
videoView.setMediaController(mc);
pBar.setVisibility(View.GONE);
mc.show(0);
FrameLayout f = (FrameLayout) mc.getParent();
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_BOTTOM, videoView.getId());
((LinearLayout) f.getParent()).removeView(f);
((RelativeLayout) videoView.getParent()).addView(f, lp);
mc.setAnchorView(videoView);
}
the problem with this solution is, that setting the anchorView doesn't have any effect and therefore tapping on the VideoView
doesn't hide/show the MediaController
as it's supposed to.
There definitly is a much better solution and hopefully someone can give me a hint!
Just wanted to add to DERIIIFranz's answer. I used the same method to assign the media controller to the view I wanted and to get the Hide() and Show() functions to work properly I simply made my own MediaController class and overrode the Hide() and Show() methods as well as the isShowing property (I'm doing this in C# with Xamarin, so I don't know what issues you would have with Java).
I also added my own click listener on the VideoView to ensure that I could handle the Hide() and Show() events myself.
public class MyMediaController : MediaController
{
private bool _isShowing { get; set; } = false;
public override bool IsShowing { get { return _isShowing; } }
public override void Show ()
{
base.Show();
_isShowing = true;
Native.ViewGroup parent = ((Native.ViewGroup)this.Parent);
parent.Visibility = Native.ViewStates.Visible;
}
public override void Hide ()
{
base.Hide();
_isShowing = false;
Native.ViewGroup parent = ((Native.ViewGroup)this.Parent);
parent.Visibility = Native.ViewStates.Gone;
}
}
To convert Jonathan Hockman's answer to Java and add it to DERIIIFranz's answer:
public class MyMediaController extends MediaController {
public MyMediaController(Context context) {
super(context);
}
public MyMediaController(Context context, boolean useFastForward) {
super (context, useFastForward);
}
public MyMediaController(Context context, AttributeSet attrs) {
super(context, attrs);
}
private boolean _isShowing = false;
@Override
public boolean isShowing() { return _isShowing; }
@Override
public void show() {
super.show();
_isShowing = true;
ViewGroup parent = (ViewGroup) this.getParent();
parent.setVisibility(View.VISIBLE);
}
@Override
public void hide() {
super.hide();
_isShowing = false;
ViewGroup parent = (ViewGroup) this.getParent();
parent.setVisibility(View.GONE);
}
}
For the videoView:
public void onPrepared(MediaPlayer mediaPlayer) {
MyMediaController mediaController = new MyMediaController(videoView.getContext(), false);
RelativeLayout parentLayout = (RelativeLayout) videoView.getParent();
RelativeLayout.LayoutParams parentParams = (RelativeLayout.LayoutParams) parentLayout.getLayoutParams();
parentParams.height = this.getHeight();
parentLayout.setLayoutParams(parentParams);
FrameLayout frameLayout = (FrameLayout) mediaController.getParent();
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, this.getId());
((ViewGroup)frameLayout.getParent()).removeView(frameLayout);
parentLayout.addView(frameLayout, layoutParams);
mediaController.setAnchorView(this);
mediaController.hide();
videoView.setMediaController(mediaController);
}