In-App Native Display Integration

This guide shows how to render NotifyVisitors Native Displays (a.k.a. in-app nudges/cards) inside your Android app using the notifyvisitors-nudges SDK. You’ll add the SDK, drop a NotifyVisitorsNativeDisplay view into your layout, load content by property_id (configured in the NotifyVisitors panel), and handle a callback to size the container.

1. Add Dependencies

Add the base SDK and the nudges module to your app module’s build.gradle:

dependencies {
    implementation "com.notifyvisitors.notifyvisitors:notifyvisitors:v5.6.0"
    implementation "com.notifyvisitors.nudges:notifyvisitors-nudges:v0.0.8"
}

Make sure the core notifyvisitors SDK is initialized the way your workspace expects (usually in Application#onCreate), before loading a native display.

2. Imports

Import the following statements:

import com.notifyvisitors.nudges.NotifyVisitorsNativeDisplay;
import com.notifyvisitors.notifyvisitors.interfaces.OnNudgeUiCompletion;
import com.notifyvisitors.notifyvisitors.NotifyVisitorsApi;

import com.notifyvisitors.nudges.NotifyVisitorsNativeDisplay
import com.notifyvisitors.notifyvisitors.interfaces.OnNudgeUiCompletion
import com.notifyvisitors.notifyvisitors.NotifyVisitorsApi

3. Code Implementation

Instantiate the view with an Activity context (not the Application context), add it to a container, and call loadContent(property_id) to fetch/render the configured native display.

NotifyVisitorsNativeDisplay nativeCardUI = new NotifyVisitorsNativeDisplay(activityContext);
nativeCardUI.loadContent(property_id_as_string);

val nativeCardUI = NotifyVisitorsNativeDisplay(activityContext)
nativeCardUI.loadContent(property_id_as_string)

Parameter:

  • property_id (String): Must exactly match the ID configured for the native display in the NotifyVisitors panel. Treat it as the unique key for the content you want to render (e.g., "home""paywall_banner""promo_card_q3").

4. Handling the Completion Callback

When the UI finishes rendering, the SDK invokes a completion callback. On success, it returns a JSON payload that typically contains a size object with the rendered height/width so you can adjust your container.

NotifyVisitorsApi.getInstance(activityContext).nudgeUiFinalized(new OnNudgeUiCompletion() {
    @Override
    public void onFinish(org.json.JSONObject info) {
        // Called when the native display finishes rendering.
        // Example payload (may vary):
        // {
        //   "success": true,
        //   "size": { "height": "180", "width": "match_parent" }
        // }
    }
});

NotifyVisitorsApi.getInstance(activityContext).nudgeUiFinalized(object : OnNudgeUiCompletion {
    override fun onFinish(info: org.json.JSONObject) {
        // Handle success + size info here
    }
})

5. Example

This example:

  1. Adds the native display view into a LinearLayout container.
  2. Loads the "home" property.
  3. Listens for the callback and dynamically updates the parent’s height on the main thread.
LinearLayout parentView = findViewById(R.id.parent_view);

NotifyVisitorsNativeDisplay nativeCardUI = new NotifyVisitorsNativeDisplay(this /* activityContext */);
parentView.addView(nativeCardUI);

// Start loading content configured as "home" in the dashboard
nativeCardUI.loadContent("home");

// Listen for completion and resize
NotifyVisitorsApi.getInstance(this).nudgeUiFinalized(new OnNudgeUiCompletion() {
    @Override
    public void onFinish(org.json.JSONObject info) {
        android.util.Log.d("App", "NUDGE INFO >> " + info);

        android.os.Handler h = new android.os.Handler(android.os.Looper.getMainLooper());
        h.post(() -> {
            try {
                org.json.JSONObject size = info.optJSONObject("size");
                if (size != null) {
                    // Height may be provided as a string
                    String heightStr = size.optString("height", "");
                    if (!heightStr.isEmpty()) {
                        int finalHeight = Integer.parseInt(heightStr);

                        ViewGroup.LayoutParams params = parentView.getLayoutParams();
                        params.height = finalHeight;
                        parentView.setLayoutParams(params);

                        android.util.Log.d("App", "Updated parent height to: " + finalHeight);
                    }
                }
            } catch (Exception e) {
                android.util.Log.e("App", "Failed to update height", e);
            }
        });
    }
});

val parentView = findViewById<LinearLayout>(R.id.parent_view)

val nativeCardUI = NotifyVisitorsNativeDisplay(this /* activityContext */)
parentView.addView(nativeCardUI)

// Start loading content configured as "home" in the dashboard
nativeCardUI.loadContent("home")

// Listen for completion and resize
NotifyVisitorsApi.getInstance(this).nudgeUiFinalized { info ->
    android.util.Log.d("App", "NUDGE INFO >> $info")

    val h = android.os.Handler(android.os.Looper.getMainLooper())
    h.post {
        try {
            val size = info.optJSONObject("size")
            if (size != null) {
                val heightStr = size.optString("height", "")
                if (heightStr.isNotEmpty()) {
                    val finalHeight = heightStr.toInt()

                    val params = parentView.layoutParams
                    params.height = finalHeight
                    parentView.layoutParams = params

                    android.util.Log.d("App", "Updated parent height to: $finalHeight")
                }
            }
        } catch (e: Exception) {
            android.util.Log.e("App", "Failed to update height", e)
        }
    }
}

6. Layout Recommendations

XML container example

<!-- res/layout/activity_main.xml -->
<LinearLayoutandroid:id="@+id/parent_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"/>

Tips

  • Start with wrap_content and let the callback size the container precisely.
  • Avoid hardcoded widths/heights inside your native display container unless you have a fixed design.
  • If the content supports dynamic updates (A/B variations, different images), always rely on the callback to finalize the size.

Further Reading

Knowledge base: Creating In-App Native Displays with NotifyVisitors (use cases, targeting, activation, troubleshooting)