1 package expo.modules.av.video 2 3 import android.annotation.SuppressLint 4 import android.content.Context 5 import android.os.Bundle 6 import android.widget.FrameLayout 7 import expo.modules.core.interfaces.DoNotStrip 8 import expo.modules.kotlin.AppContext 9 import expo.modules.kotlin.viewevent.EventDispatcher 10 11 /** 12 * We need the wrapper to be able to remove the view from the React-managed tree 13 * into the FullscreenVideoPlayer and not have to fight with the React styles 14 * overriding our native layout. 15 */ 16 @SuppressLint("ViewConstructor") 17 @DoNotStrip 18 class VideoViewWrapper @DoNotStrip constructor(context: Context, appContext: AppContext) : FrameLayout(context) { 19 val videoViewInstance: VideoView <lambda>null20 private val mLayoutRunnable = Runnable { 21 measure( 22 MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), 23 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY) 24 ) 25 layout(left, top, right, bottom) 26 } 27 requestLayoutnull28 override fun requestLayout() { 29 super.requestLayout() 30 31 // Code borrowed from: 32 // https://github.com/facebook/react-native/blob/d19afc73f5048f81656d0b4424232ce6d69a6368/ReactAndroid/src/main/java/com/facebook/react/views/toolbar/ReactToolbar.java#L166 33 34 // It fixes two bugs: 35 // - ExpoMediaController's height = 0 when initialized (until relayout) 36 // - blank VideoView (until relayout) after dismissing FullscreenVideoPlayer 37 post(mLayoutRunnable) 38 } 39 40 init { 41 videoViewInstance = VideoView(context, this, appContext) 42 addView(videoViewInstance, generateDefaultLayoutParams()) 43 } 44 45 //region view callbacks 46 47 val onStatusUpdate by EventDispatcher<Bundle>() 48 val onLoadStart by EventDispatcher<Unit>() 49 val onLoad by EventDispatcher<Bundle>() 50 val onError by EventDispatcher<Bundle>() 51 val onReadyForDisplay by EventDispatcher<Bundle>() 52 val onFullscreenUpdate by EventDispatcher<Bundle>() 53 54 //endregion 55 } 56