androidreact-nativegoogle-ima

Google IMA webview is not showing when used inside react native on android


In short: We use reacte native on android and use the native VideoView to show videos with ads using the Google IMA SDK for android. The video plays, the ads play, but the Webview containing "read more" and "skip ad" is not visible. It's added to the view hierarchy, but it's size 0,0 and it has no children. When I use the exact same code in a native app. Everything works as expected.

Some more context:

Relevant code from the React Native component:

@SuppressLint("ViewConstructor")
public class ReactVideoViewWithAds extends FrameLayout implements
    LifecycleEventListener {

private VideoPlayerWithAdPlayback mVideoPlayerWithAdPlayback;
private RelativeLayout mCompanionAdSlot;
private VideoPlayerController mVideoPlayerController;

public ReactVideoViewWithAds(ThemedReactContext themedReactContext) {
    super(themedReactContext);
    createViews();
    themedReactContext.addLifecycleEventListener(this);
}

private void createViews() {

    FrameLayout.LayoutParams companionAdLayoutParams = new FrameLayout.LayoutParams(
            FrameLayout.LayoutParams.MATCH_PARENT,
            (int) (50 * getResources().getSystem().getDisplayMetrics().density));
    companionAdLayoutParams.gravity = Gravity.CENTER_HORIZONTAL;
    mCompanionAdSlot = new RelativeLayout(getContext());
    mCompanionAdSlot.setBackgroundColor(Color.BLUE);
    addView(mCompanionAdSlot, companionAdLayoutParams);

    //player with ad playback
    FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
            FrameLayout.LayoutParams.MATCH_PARENT,
            FrameLayout.LayoutParams.MATCH_PARENT);
    mVideoPlayerWithAdPlayback = new VideoPlayerWithAdPlayback(getContext());
    addView(mVideoPlayerWithAdPlayback, layoutParams);


    initPlayer();
}

private void initPlayer() {
    mVideoPlayerController = new VideoPlayerController(
            getContext(),
            mVideoPlayerWithAdPlayback,
            null,
            null,
            "nl",
            mCompanionAdSlot,
            null);
}

Solution

  • This question had the solution in a comment

    When adding views dynamically in a native component it seems you need to manually trigger a layout cycle in order for react-native to pick up on the changes. (perhaps related to react native updating it's shadow-view)

     @Override
        public void requestLayout() {
            super.requestLayout();
            post(measureAndLayout);
        }
    
        private final Runnable measureAndLayout = new Runnable() {
            @Override
            public void run() {
                measure(
                        MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
                        MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
                layout(getLeft(), getTop(), getRight(), getBottom());
            }
        };