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.
Contents
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 questions, please feel free to leave a comment below