Maxim Kirilov
Maxim Kirilov

Reputation: 2749

How to add an ad view in ConstraintLayout at bottom and below other stuff programmatically?

This question may look similar to the following question, but I need help solving my use case. It provides explanations for adding constraints inside the XML file.

I'm trying to migrate from RelativeLayout to ConstraintLayout, but I need help programmatically adding the ad view to the bottom and the rest of the content above it. I chose the code approach to allow dynamic padding that we receive from a backend server.

Previously, I used a FramedLayout to hold the ad view (banner). As a result, the WebView above was resized automatically during the view update (I don't know the best solution) and shrank upon ad removal.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    <WebView
        android:id="@+id/webview"
        android:background="#000000"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:animateLayoutChanges="true"
        android:layout_above="@id/ad_view_container_bottom"
    />

    <FrameLayout
        android:id="@+id/ad_view_container_bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_alignParentBottom="true">
    </FrameLayout>

</RelativeLayout>

I want to add the ad view programmatically to the bottom of the screen and make the WebView resize to fit the screen. I tried the following ConstraintLayout, but it places the ad view container beneath the WebView without resizing it (the ad is not visible).

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:animateLayoutChanges="true"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>

    <FrameLayout
        android:id="@+id/ad_view_container_bottom"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/webview"
        app:layout_constraintBottom_toBottomOf="parent">
    </FrameLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

My questions are:

  1. What is the correct way to place the ad view beneath the WebView?
  2. Do I need the FrameLayout, or can I achieve it more straightforwardly (the width is screen width, and the height size is fixed)?
  3. Do I gain any performance improvement here regarding screen rendering (less layout-and-measure stages)?

Upvotes: 0

Views: 30

Answers (1)

Sanjay
Sanjay

Reputation: 400

1. Correct way to place the ad view beneath the WebView:

In ConstraintLayout, to position views relative to each other, you need to define constraints that tie one view's position to another. To place the ad view below the WebView and ensure it behaves as expected (with the WebView resizing accordingly), you need to set the following constraints:

The WebView should have a constraint to the top, left, and right edges of the parent, And bottom to top of the ad Container.

The ad container (FrameLayout) should have a constraint to the bottom of the WebView and the bottom of the parent container.

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/constraint_layout"
    tools:context=".MainActivity">

    <WebView
        android:id="@+id/webview"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:animateLayoutChanges="true"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/ad_view_container_bottom"/>

    <FrameLayout
        android:id="@+id/ad_view_container_bottom"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent">
    </FrameLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

To Programmatically set the constraints:

val layout: ConstraintLayout = findViewById(R.id.constraint_layout)
val webView: WebView = findViewById(R.id.webview)
val adViewContainer: FrameLayout = findViewById(R.id.ad_view_container_bottom)

val constraintSet = ConstraintSet()
constraintSet.clone(layout)
constraintSet.connect(webView.id, ConstraintSet.TOP, layout.id, ConstraintSet.TOP, 0)
constraintSet.connect(webView.id, ConstraintSet.LEFT, layout.id, ConstraintSet.LEFT, 0)
constraintSet.connect(webView.id, ConstraintSet.RIGHT, layout.id, ConstraintSet.RIGHT, 0)
constraintSet.connect(webView.id, ConstraintSet.BOTTOM, adViewContainer.id, ConstraintSet.TOP, 0)

constraintSet.connect(adViewContainer.id, ConstraintSet.BOTTOM, layout.id, ConstraintSet.BOTTOM, 0)
constraintSet.connect(adViewContainer.id, ConstraintSet.LEFT, layout.id, ConstraintSet.LEFT, 0)
constraintSet.connect(adViewContainer.id, ConstraintSet.RIGHT, layout.id, ConstraintSet.RIGHT, 0)

constraintSet.applyTo(layout)

To set padding:

adViewContainer.setPadding(0, 0, 0, 16); 
webView.setPadding(16, 16, 16, 16);

2. Do you need the FrameLayout?

If the ad view's width is fixed to match the screen width, and its height is fixed as well (for example, a banner ad with a fixed height), you can avoid using a FrameLayout and simply use a View or ConstraintLayout child with the specified height. If you want to use a FrameLayout (which is a common container for ads), that will work as well, but it’s not necessary for a simple case where you are just positioning the ad view at the bottom.

3. Performance Improvement:

Using ConstraintLayout generally improves performance compared to other layouts like RelativeLayout, especially when there are many nested views. This is because ConstraintLayout minimizes the number of passes required during the layout and measurement stages. With fewer layers and more direct constraints, it can perform faster. But Difference is highly negligible for simple views.

Upvotes: 0

Related Questions