How to create a Popup Window in Android using Kotlin

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
Brian Miranda

I’m trying to make two buttons. One will go back to the original screen, and the other will go to the next screen.

Matthew Easton

Excellent tutorial, thanks.

Hansi

Super Erklärung

Thank you very much

larglarg

I am trying to do this but if I try to run this and press the button to start the overlay I get this error can someone help me ??

E/AndroidRuntime: FATAL EXCEPTION: main
   Process: com.example.popup, PID: 8460
   android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.popup/com.example.popup.PopUpWindow}; have you declared this activity in your AndroidManifest.xml?
       at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1932)
       at android.app.Instrumentation.execStartActivity(Instrumentation.java:1615)
       at android.app.Activity.startActivityForResult(Activity.java:4472)
       at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:676)
       at android.app.Activity.startActivityForResult(Activity.java:4430)
       at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:663)
       at android.app.Activity.startActivity(Activity.java:4791)
       at android.app.Activity.startActivity(Activity.java:4759)
       at com.example.popup.MainActivity$onCreate$1.onClick(MainActivity.kt:19)
       at android.view.View.performClick(View.java:6256)
       at android.view.View$PerformClick.run(View.java:24701)
       at android.os.Handler.handleCallback(Handler.java:789)
       at android.os.Handler.dispatchMessage(Handler.java:98)
       at android.os.Looper.loop(Looper.java:164)
       at android.app.ActivityThread.main(ActivityThread.java:6541)
       at java.lang.reflect.Method.invoke(Native Method)
       at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

sry for writing mistakes xD (not in the error in my text xD)

Kamil

I have a small problem my program doesn’t recognize show_btn after creating one