How to create a Popup Window in Android using Kotlin

Last updated on: May 27, 2023

Today, I’m going to show you how to create very easy a nice popup window with a semi-transparent background!

In this example I’m using CardView to have rounded corners in the popup window. If you don’t like it, and you want to use something else (RelativeLayout, FrameLayout e.t.c), just skip the next step.

Adding the CardView library

If you like your popup window to have rounded corners, add the cardView library to your build.gradle of your app module

dependencies {
    // ...
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    // ...
}Code language: Kotlin (kotlin)

Creating the Popup Window Activity

Create a new Empty Activity in your project. In this example, we call it PopUpWindow

Go to the xml layout and paste the following code:

<?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:id="@+id/popup_window_background"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".PopUpWindow">


    <androidx.cardview.widget.CardView
        android:id="@+id/popup_window_view_with_border"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        app:cardBackgroundColor="#FFFFFF"
        app:cardCornerRadius="3dp"
        app:cardElevation="0dp"
        app:cardMaxElevation="0dp"
        app:cardPreventCornerOverlap="false"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <androidx.cardview.widget.CardView
            android:id="@+id/popup_window_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_margin="2dp"
            app:cardBackgroundColor="@android:color/white"
            app:cardCornerRadius="3dp"
            app:cardElevation="0dp"
            app:cardMaxElevation="0dp"
            app:cardPreventCornerOverlap="false">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/popup_window_background_container"
                android:layout_width="250dp"
                android:minHeight="170dp"
                android:background="#bc214b"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true">

                <androidx.appcompat.widget.AppCompatTextView
                    android:id="@+id/popup_window_text"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginStart="8dp"
                    android:layout_marginTop="8dp"
                    android:layout_marginEnd="8dp"
                    android:layout_marginBottom="8dp"
                    android:text="Text"
                    android:gravity="center"
                    android:textAlignment="center"
                    android:textStyle="bold"
                    android:textColor="#FFFFFF"
                    android:textSize="12sp"
                    app:layout_constraintBottom_toTopOf="@+id/popup_window_button"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@+id/popup_window_title" />

                <androidx.appcompat.widget.AppCompatTextView
                    android:id="@+id/popup_window_title"
                    android:layout_width="match_parent"
                    android:layout_height="45dp"
                    app:autoSizeTextType="uniform"
                    app:autoSizeMaxTextSize="24dp"
                    android:background="#9E1C40"
                    android:text="Title"
                    android:gravity="center"
                    android:textAlignment="center"
                    android:textColor="#FFFFFF"
                    android:textSize="20sp"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />


                <Button
                    android:id="@+id/popup_window_button"
                    style="?android:attr/borderlessButtonStyle"
                    android:layout_width="match_parent"
                    android:layout_height="40dp"
                    android:background="#851635"
                    android:text="ok"
                    android:textAllCaps="false"
                    android:textColor="#FFFFFF"
                    android:textSize="20sp"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent" />

            </androidx.constraintlayout.widget.ConstraintLayout>

        </androidx.cardview.widget.CardView>
    </androidx.cardview.widget.CardView>

</androidx.constraintlayout.widget.ConstraintLayout>Code language: HTML, XML (xml)

Go to your activity file (PopUpWindow.kt) and disable Activity’s open/close animation by giving the number 0 on the overridePendingTransition before the setContentView

class PopUpWindow : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        overridePendingTransition(0, 0)
        setContentView(R.layout.popup_window)

        // ...
    }
}Code language: Kotlin (kotlin)

Use Bundle to get the data we’ll pass later on when we call the popup window from the MainActivity

class PopUpWindow : AppCompatActivity() {
    private var popupTitle = ""
    private var popupText = ""
    private var popupButton = ""
    private var darkStatusBar = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...

        // Get the data
        val bundle = intent.extras
        popupTitle = bundle?.getString("popuptitle", "Title") ?: ""
        popupText = bundle?.getString("popuptext", "Text") ?: ""
        popupButton = bundle?.getString("popupbtn", "Button") ?: ""
        darkStatusBar = bundle?.getBoolean("darkstatusbar", false) ?: false

    }
}Code language: Kotlin (kotlin)

Set the data to the TextViews and Button

class PopUpWindow : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...

        // Set the data
        popup_window_title.text = popupTitle
        popup_window_text.text = popupText
        popup_window_button.text = popupButton
        
        // ...
    }
}Code language: Kotlin (kotlin)

Make the status bar appearance transparent at different API levels

class PopUpWindow : AppCompatActivity() {
    private var popupTitle = ""
    private var popupText = ""
    private var popupButton = ""
    private var darkStatusBar = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...

        // Set the Status bar appearance for different API levels
        if (Build.VERSION.SDK_INT in 19..20) {
            setWindowFlag(this, true)
        }
        if (Build.VERSION.SDK_INT >= 19) {
            window.decorView.systemUiVisibility =
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        }
        if (Build.VERSION.SDK_INT >= 21) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                // If you want dark status bar, set darkStatusBar to true
                if (darkStatusBar) {
                    this.window.decorView.systemUiVisibility =
                        View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
                }
                this.window.statusBarColor = Color.TRANSPARENT
                setWindowFlag(this, false)
            }
        }
      
        // ...
    }

    private fun setWindowFlag(activity: Activity, on: Boolean) {
        val win = activity.window
        val winParams = win.attributes
        if (on) {
            winParams.flags = winParams.flags or WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
        } else {
            winParams.flags = winParams.flags and WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS.inv()
        }
        win.attributes = winParams
    }
}Code language: Kotlin (kotlin)

Create a fade animation for the popup window background when the Activity starts

class PopUpWindow : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...

        // Fade animation for the background of Popup Window
        val alpha = 100 //between 0-255
        val alphaColor = ColorUtils.setAlphaComponent(Color.parseColor("#000000"), alpha)
        val colorAnimation = ValueAnimator.ofObject(ArgbEvaluator(), Color.TRANSPARENT, alphaColor)
        colorAnimation.duration = 500 // milliseconds
        colorAnimation.addUpdateListener { animator ->
            popup_window_background.setBackgroundColor(animator.animatedValue as Int)
        }
        colorAnimation.start()
      
       
        // ...
    }
}Code language: Kotlin (kotlin)

Create the fade animation for the popup window too

class PopUpWindow : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...

        // Fade animation for the Popup Window
        popup_window_view_with_border.alpha = 0f
        popup_window_view_with_border.animate().alpha(1f).setDuration(500).setInterpolator(
            DecelerateInterpolator()
        ).start()

        // ...
        
    }
}Code language: Kotlin (kotlin)

Close the popup window with fade animation when you press the ‘OK’ button or the back button on your device.

class PopUpWindow : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
      
        // Close the Popup Window when you press the button
        popup_window_button.setOnClickListener {
            onBackPressed()
        }
    }

    override fun onBackPressed() {
        // Fade animation for the background of Popup Window when you press the back button
        val alpha = 100 // between 0-255
        val alphaColor = ColorUtils.setAlphaComponent(Color.parseColor("#000000"), alpha)
        val colorAnimation = ValueAnimator.ofObject(ArgbEvaluator(), alphaColor, Color.TRANSPARENT)
        colorAnimation.duration = 500 // milliseconds
        colorAnimation.addUpdateListener { animator ->
            popup_window_background.setBackgroundColor(
                animator.animatedValue as Int
            )
        }

        // Fade animation for the Popup Window when you press the back button
        popup_window_view_with_border.animate().alpha(0f).setDuration(500).setInterpolator(
            DecelerateInterpolator()
        ).start()

        // After animation finish, close the Activity
        colorAnimation.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                finish()
                overridePendingTransition(0, 0)
            }
        })
        colorAnimation.start()
    }

}Code language: Kotlin (kotlin)

Using the Popup Window

To use the popup window, just pass the values for the Title, Text, Button text and Status Bar appearance.

In this example, when you press the button in the MainActivity, it shows the popup window with title ‘Error’ and text ‘Sorry, that email address is already used!’

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        show_btn.setOnClickListener {
            val intent = Intent(this, PopUpWindow::class.java)
            intent.putExtra("popuptitle", "Error")
            intent.putExtra("popuptext", "Sorry, that email address is already used!")
            intent.putExtra("popupbtn", "OK")
            intent.putExtra("darkstatusbar", false)
            startActivity(intent)
        }
    }
}Code language: Kotlin (kotlin)
You can find the final project here

If you have any questionsplease feel free to leave a comment below

Subscribe
Notify of
guest
8 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments