SkillAgentSearch skills...

Balloon

:balloon: Modernized and sophisticated tooltips, fully customizable with an arrow and animations for Android and Jetpack Compose.

Install / Use

/learn @skydoves/Balloon

README

<h1 align="center">Balloon</h1></br> <p align="center"> :balloon: Modernized and sophisticated tooltips, fully customizable with an arrow and animations on Android. </p> </br> <p align="center"> <a href="https://devlibrary.withgoogle.com/products/android/repos/skydoves-Balloon"><img alt="Google" src="https://skydoves.github.io/badges/google-devlib.svg"/></a> <a href="https://twitter.com/googledevs/status/1476223093773418502"><img alt="Twitter" src="https://skydoves.github.io/badges/twitter-developers.svg"/></a> <a href="https://www.linkedin.com/feed/update/urn:li:activity:6881990083344519168/"><img alt="LinkedIn" src="https://skydoves.github.io/badges/linkedin-developers.svg"/></a> <a href="https://github.com/doveletter"><img alt="Profile" src="https://skydoves.github.io/badges/dove-letter.svg"/></a><br> <a href="https://opensource.org/licenses/Apache-2.0"><img alt="License" src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"/></a> <a href="https://android-arsenal.com/api?level=21"><img alt="API" src="https://img.shields.io/badge/API-21%2B-brightgreen.svg?style=flat"/></a> <a href="https://github.com/skydoves/Balloon/actions"><img alt="Build Status" src="https://github.com/skydoves/Balloon/workflows/Android%20CI/badge.svg"/></a> <a href="https://medium.com/swlh/a-lightweight-tooltip-popup-for-android-ef9484a992d7"><img alt="Medium" src="https://skydoves.github.io/badges/Story-Medium.svg"/></a> <a href="https://github.com/skydoves"><img alt="Profile" src="https://skydoves.github.io/badges/skydoves.svg"/></a> <a href="https://skydoves.github.io/libraries/balloon/html/balloon/com.skydoves.balloon/index.html"><img alt="Dokka" src="https://skydoves.github.io/badges/dokka-balloon.svg"/></a> </p> <br> <p align="center"> <img src="https://user-images.githubusercontent.com/24237865/61194943-f9d70380-a6ff-11e9-807f-ba1ca8126f8a.gif" width="280"/> <img src="https://user-images.githubusercontent.com/24237865/61225579-d346b600-a75b-11e9-84f8-3c06047b5003.gif" width="280"/> <img src="https://user-images.githubusercontent.com/24237865/148673977-dba2e44c-c2fb-4fb4-a648-e26e8541e865.png" width="252"/> </p>

Who's using Balloon?

👉 Check out who's using Balloon

Balloon hits +800,000 downloads every month around the globe! :balloon:

globe

<img align="right" width="130px" src="https://user-images.githubusercontent.com/24237865/210227682-cbc03479-8625-4213-b907-4f15217f91ba.png"/>

Balloon in Jetpack Compose

If you want to use Balloon in your Jetpack Compose project, check out the Balloon in Jetpack Compose section. You can also check out the blog post Tooltips for Jetpack Compose: Improve User Experience to the Next Level for more details.

💝 Sponsors

<a href="https://coderabbit.link/Jaewoong" target="_blank"> <img width="300" alt="coderabbit" src="https://www.coderabbit.ai/_next/image?url=https%3A%2F%2Fvictorious-bubble-f69a016683.media.strapiapp.com%2FCr_logo_dark_f656abe8e3.png&w=384&q=75" /></a>

<a href="https://getstream.io/chat/sdk/android/?utm_source=github&utm_medium=referral&utm_content=&utm_campaign=Jaewoong_github_2025" target="_blank"> <img width="260" alt="stream" src="https://github.com/user-attachments/assets/87a69228-4fef-4f48-ad98-1e2c606c5b7e" /></a>

Including in your project

Maven Central

Gradle

Add the dependency below to your module's build.gradle file:

dependencies {
    implementation("com.github.skydoves:balloon:1.7.5")
}

How to Use

Balloon supports both Kotlin and Java projects, so you can reference it by your language.

Create Balloon with Kotlin

We can create an instance of the Balloon with the Balloon.Builder class.

val balloon = Balloon.Builder(context)
  .setWidthRatio(1.0f)
  .setHeight(BalloonSizeSpec.WRAP)
  .setText("Edit your profile here!")
  .setTextColorResource(R.color.white_87)
  .setTextSize(15f)
  .setIconDrawableResource(R.drawable.ic_edit)
  .setArrowPositionRules(ArrowPositionRules.ALIGN_ANCHOR)
  .setArrowSize(10)
  .setArrowPosition(0.5f)
  .setPadding(12)
  .setCornerRadius(8f)
  .setBackgroundColorResource(R.color.skyBlue)
  .setBalloonAnimation(BalloonAnimation.ELASTIC)
  .setLifecycleOwner(lifecycle)
  .build()

Create Balloon with Kotlin DSL

We can also create an instance of the Balloon with the Kotlin DSL.

<details> <summary>Keep reading for more details</summary>

You can create an instance of the Balloon with createBalloon as the example below:

val balloon = createBalloon(context) {
  setWidthRatio(1.0f)
  setHeight(BalloonSizeSpec.WRAP)
  setText("Edit your profile here!")
  setTextColorResource(R.color.white_87)
  setTextSize(15f)
  setIconDrawableResource(R.drawable.ic_edit)
  setArrowPositionRules(ArrowPositionRules.ALIGN_ANCHOR)
  setArrowSize(10)
  setArrowPosition(0.5f)
  setPadding(12)
  setCornerRadius(8f)
  setBackgroundColorResource(R.color.skyBlue)
  setBalloonAnimation(BalloonAnimation.ELASTIC)
  setLifecycleOwner(lifecycle)
  build()
}
</details>

Create Balloon with Java

You can create an instance of the Balloon with Java by using the Balloon.Builder class.

<details> <summary>Keep reading for more details</summary>

You can create an instance of the Balloon as the following example below:

Balloon balloon = new Balloon.Builder(context)
    .setArrowSize(10)
    .setArrowOrientation(ArrowOrientation.TOP)
    .setArrowPositionRules(ArrowPositionRules.ALIGN_ANCHOR)
    .setArrowPosition(0.5f)
    .setWidth(BalloonSizeSpec.WRAP)
    .setHeight(65)
    .setTextSize(15f)
    .setCornerRadius(4f)
    .setAlpha(0.9f)
    .setText("You can access your profile from now on.")
    .setTextColor(ContextCompat.getColor(context, R.color.white_93))
    .setTextIsHtml(true)
    .setIconDrawable(ContextCompat.getDrawable(context, R.drawable.ic_profile))
    .setBackgroundColor(ContextCompat.getColor(context, R.color.colorPrimary))
    .setOnBalloonClickListener(onBalloonClickListener)
    .setBalloonAnimation(BalloonAnimation.FADE)
    .setLifecycleOwner(lifecycleOwner)
    .build();
</details>

Show up Balloon

We can show up the Balloon using the functions below. If we use showAlign__ method, we can show up the Balloon based on alignments (top, bottom, right, left). Also, we can adjust specific positions of the Balloon by using x-Offset and y-Offset parameters. <br>

balloon.showAlignTop(anchor: View) // shows the balloon on an anchor view as the top alignment.
balloon.showAlignTop(anchor: View, xOff: Int, yOff: Int) // shows top alignment with x-off and y-off.
balloon.showAlignBottom(anchor: View) // shows the balloon on an anchor view as the bottom alignment.
balloon.showAlignBottom(anchor: View, xOff: Int, yOff: Int) // shows bottom alignment with x-off and y-off.
balloon.showAlignEnd(anchor: View) // shows the balloon on an anchor view as the end alignment.
balloon.showAlignEnd(anchor: View, xOff: Int, yOff: Int) // shows end alignment with x-off and y-off.
balloon.showAlignStart(anchor: View) // shows the balloon on an anchor view as the start alignment.
balloon.showAlignStart(anchor: View, xOff: Int, yOff: Int) // shows start alignment with x-off and y-off.
balloon.showAsDropDown(anchor: View) // shows the balloon as a dropdown without any alignments.
balloon.showAsDropDown(anchor: View, xOff: Int, yOff: Int) // shows no alignments with x-off and y-off.
balloon.showAtCenter(anchor: View, xOff: Int, yOff: Int, centerAlign: BalloonCenterAlign.TOP)
// shows the balloon over the anchor view (overlap) as the center aligns.

Also, We can show up the Balloon with Kotlin extensions.

myButton.showAlignTop(balloon)

Dismiss Balloon

We can dismiss the Balloon by using the Balloon.dismiss() method.

balloon.dismiss()
balloon.dismissWithDelay(1000L) // dismisses 1000 milliseconds later when the popup is shown

We can dismiss automatically with a delay after the Balloon is shown using the setAutoDismissDuration method.

Balloon.Builder(context)
   // dismisses automatically 1000 milliseconds later when the popup is shown.
   .setAutoDismissDuration(1000L)
   ...

Show up Balloon Sequentially

We can show up a couple of Balloons sequentially with the relayShow__ and await__ methods.

customListBalloon
  .relayShowAlignBottom(customProfileBalloon, circleImageView) // relay to customListBalloon
  .relayShowAlignTop(customTagBalloon, bottomNavigationView, 130, 0) // relay to customProfileBalloon

// show sequentially customListBalloon-customProfileBalloon-customTagBalloon
customListBalloon.showAlignBottom(anchorView)
coroutineScope.launch {
  customListBalloon.awaitAlignBottom(anchorView)
  customProfileBalloon.awaitAlignBottom(circleImageView, 0, 0)
  customTagBalloon.awaitAlignTop(bottomNavigationView, 130, 0)
}

Note: The relayShow__ and await__ methods overwrite the setOnDismissListener internally, so you can't use the setOnDismissListener at the same time.

Parallel Displaying

We can show multiple balloons at the same time with sequential behavior.

lifecycleScope.launch {
  // shows balloons at the same time
  awaitBalloons {
    // dismissing of any balloon dismisses all of them. Default behaviour
    dismissSequentially = false

    textView.alignTop(balloonAlignTop)
    textView.alignStart(balloonAlignStart)
    textView.alignEnd(balloonAlignEnd)
    textView.alignBottom(balloonAlignBottom)
  }

  // s
View on GitHub
GitHub Stars4.0k
CategoryDevelopment
Updated18h ago
Forks309

Languages

Kotlin

Security Score

100/100

Audited on Mar 26, 2026

No findings