XamarinMediaManager icon indicating copy to clipboard operation
XamarinMediaManager copied to clipboard

VideoView cannot be attached outside of OnElementChanged in Xamarin.Forms

Open LittleBoxOfChicken opened this issue 4 years ago • 0 comments

🐛 Bug Report

I have spent so much time trying to work around this.

I have a view that contains multiple VideoViews. I understand that I need to switch between them when this is the case by setting CrossMediaManager.Current.MediaPlayer.VideoView = _videoView;.

I've also set CrossMediaManager.Current.MediaPlayer.AutoAttachVideoView = false;

I made a CustomVideoViewRenderer so that I have control over the native IVideoView.

public class CustomVideoViewRendererAndroid : VideoViewRenderer
{
    private MediaManager.Platforms.Android.Video.VideoView _videoView;

    public CustomVideoViewRendererAndroid(Context context) : base(context)
    {

    }

    protected override void OnElementChanged(ElementChangedEventArgs<VideoView> args)
    {
        if (args.OldElement != null)
        {
            args.OldElement.Dispose();
        }

        if (args.NewElement != null)
        {
            if (Control == null)
            {
                _videoView = new MediaManager.Platforms.Android.Video.VideoView(Context);
                CrossMediaManager.Current.MediaPlayer.VideoView = _videoView;
                SetNativeControl(_videoView);
                UpdateBackgroundColor();
                UpdateLayout();
            }
        }

        base.OnElementChanged(args);
    }

    protected override void UpdateBackgroundColor()
    {
        base.UpdateBackgroundColor();
        Control?.SetShutterBackgroundColor(Element.BackgroundColor.ToAndroid());
    }

    protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        if (_videoView != null && widthMeasureSpec > -1 && heightMeasureSpec > -1)
        {
            var p = _videoView.LayoutParameters;

            if (p == null)
                p = new LayoutParams(widthMeasureSpec, heightMeasureSpec);
            else
            {
                p.Height = heightMeasureSpec;
                p.Width = widthMeasureSpec;
            }
            _videoView.LayoutParameters = p;
        }
        base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    protected override void Dispose(bool disposing)
    {
        //On Android we need to call this manually it seems, since args.OldElement is never filled
        Element?.Dispose();

        _videoView = null;
        base.Dispose(disposing);
    }
}

This works. However, it's not what I need. Instead I need to set the current VideoView when it comes into frame. The calls all work and it all happens smoothly.

private void AttachChanged(object sender, bool e)
{
    CrossMediaManager.Current.MediaPlayer.VideoView = _videoView;
}

This line is reached and executed fine. After this line I can inspect CrossMediaManager.Current.MediaPlayer.VideoView and see that it is indeed set to the VideoView that I want the controls to be linked to however the Controls do not apear on the page.

I truly hope that I'm missing something here. When I re-enable CrossMediaManager.Current.MediaPlayer.AutoAttachVideoView = true; everything works again fine but the 2 VideoViews I am using are synced up and are attached to the same audio source it seems.

Version: 1.0.8

Platform:

  • [ ] :iphone: iOS
  • [ ] :robot: Android
  • [ ] :checkered_flag: WPF
  • [ ] :earth_americas: UWP
  • [ ] :apple: MacOS
  • [ ] :tv: tvOS
  • [x] :monkey: Xamarin.Forms

LittleBoxOfChicken avatar Feb 19 '21 13:02 LittleBoxOfChicken