:balloon: A lightweight popup like tooltips, fully customizable with an arrow and animations.

Overview

Balloon


🎈 A lightweight popup like tooltips, fully customizable with arrow and animations.


License API Build Status Medium Profile Javadoc


Including in your project

Maven Central Balloon

Gradle

Add below codes to your root build.gradle file (not your module build.gradle file).

allprojects {
    repositories {
        mavenCentral()
    }
}

And add a dependency code to your module's build.gradle file.

dependencies {
    implementation "com.github.skydoves:balloon:1.3.3"
}

SNAPSHOT

Balloon
Snapshots of the current development version of Balloon are available, which track the latest versions.

repositories {
   maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}

Usage

Basic Example for Java

Here is a basic example of implementing balloon popup with icon and text using Balloon.Builder class.

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();

Create using kotlin dsl

This is how to create Balloon instance using kotlin dsl.

val balloon = createBalloon(context) {
  setArrowSize(10)
  setWidth(BalloonSizeSpec.WRAP)
  setHeight(65)
  setArrowPosition(0.7f)
  setCornerRadius(4f)
  setAlpha(0.9f)
  setText("You can access your profile from now on.")
  setTextColorResource(R.color.white_93)
  setTextIsHtml(true)
  setIconDrawable(ContextCompat.getDrawable(context, R.drawable.ic_profile))
  setBackgroundColorResource(R.color.colorPrimary)
  setOnBalloonClickListener(onBalloonClickListener)
  setBalloonAnimation(BalloonAnimation.FADE)
  setLifecycleOwner(lifecycleOwner)
}

Width and height

We can handle sizes of the popup width and height using the below ways.
If we would not set any specific sizes of the width/height of the balloon, the size of the popup will be decided by the content.

Padding

Balloon wraps a content. We can control the content size of the balloon using padding of the content.

balloon.setPadding(6) // sets 6dp padding to all directions (left-top-right-bottom)
balloon.setPaddingLeft(8) // sets 8dp padding to content's left.
balloon.setPaddingTop(12) // sets 12dp padding to content's top.

Specific size

We can set the specific size of the balloon regardless size of the contents.

balloon.setWidth(220) // sets 220dp width size.
balloon.setHeight(160) // sets 160dp height size.
balloon.setWidth(BalloonSizeSpec.WRAP) // sets width size depending on the content's size.
balloon.setHeight(BalloonSizeSpec.WRAP) // sets height size depending on the content's size.

According to screen ratio

Also, we can set the width according to the ratio of the horizontal screen's size.

balloon.setWidthRatio(0.5f) // sets width as 50% of the horizontal screen's size.

Show and dismiss

This is how to show balloon popup and dismiss.
We can set the balloon popup's position using x-Offset and y-Offset attributes.
And show based on top/bottom/right/left alignment if we use showAlign__ method.

balloon.show(anchor: View) // shows the balloon on the center of an anchor view.
balloon.show(anchor: View, xOff: Int, yOff: Int) // shows the balloon on an anchor view with x-off and y-off.
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.showAlignRight(anchor: View) // shows the balloon on an anchor view as the right alignment.
balloon.showAlignRight(anchor: View, xOff: Int, yOff: Int) // shows right alignment with x-off and y-off.
balloon.showAlignLeft(anchor: View) // shows the balloon on an anchor view as the left alignment.
balloon.showAlignLeft(anchor: View, xOff: Int, yOff: Int) // shows left alignment with x-off and y-off.

Or we can show balloon popup using kotlin extension.

myButton.showAlignTop(balloon)

We can dismiss popup simply using Balloon.dismiss() method.

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

We can dismiss automatically some milliseconds later when the popup is shown using
setAutoDismissDuration method on Balloon.Builder.

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

Show sequentially

We can show balloon popup sequentially using relayShow method.
The relayShow method makes that setOnDismissListener of the first balloon is reset to show the
next balloon and returns an instance of the next balloon.

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

// show sequentially customListBalloon-customProfileBalloon-customTagBalloon
customListBalloon.showAlignBottom(toolbar_list)

Margin

If the location of the balloon according to the anchor is located at the boundaries on the screen,
the balloon will be stick to the end of the screen. In that case, we can resolve by giving margins to the balloon.

.setMargin(12) // sets the margin on the balloon all directions.
.setMarginLeft(14) // sets the left margin on the balloon.
.setMarginRight(14) // sets the right margin on the balloon.

Arrow Composition

We can customize the arrow on the balloon popup.

.setIsVisibleArrow(true) // sets the visibility of the arrow.
.setArrowSize(10) // sets the arrow size.
.setArrowSize(BalloonSizeSpec.WRAP) // sets arrow size depending on the original resources' size.
.setArrowPosition(0.8f) // sets the arrow position using the popup size's ratio (0 ~ 1.0)
.setArrowOrientation(ArrowOrientation.TOP) // sets the arrow orientation. top, bottom, left, right
.setArrowDrawable(ContextCompat.getDrawable(context, R.drawable.arrow)) // sets the arrow drawable.

ArrowPositionRules

We can determine the position of the arrow depending on the aligning rules using the ArrowPositionRules.

// Align the arrow position depending on an anchor.
// if `arrowPosition` is 0.5, the arrow will be located in the middle of an anchor.
.setArrowPositionRules(ArrowPositionRules.ALIGN_ANCHOR) // default

// Align the arrow position depending on the balloon popup body.
// if `arrowPosition` is 0.5, he arrow will be located in the middle of the tooltip.
.setArrowPositionRules(ArrowPositionRules.ALIGN_BALLOON)

ArrowOrientationRules

We can determine the orientation of the arrow depending on the aligning rules using the ArrowOrientationRules.

// Align depending on the position of an anchor.
// For example, `arrowOrientation` is ArrowOrientation.TOP and 
// we want to show up the balloon under an anchor using the `Balloon.showAlignBottom`.
// However, if there is not enough free space to place the tooltip at the bottom of the anchor,
// tooltips will be placed top of the anchor and the orientation of the arrow will be `ArrowOrientation.BOTTOM`.
.setArrowOrientationRules(ArrowOrientationRules.ALIGN_ANCHOR) // default

// Align to fixed ArrowOrientation value.
.setArrowOrientationRules(ArrowOrientationRules.ALIGN_FIXED)

Below previews are implemented using setArrowOrientation and setArrowPosition methods.
setArrowPosition measures the balloon popup size and sets the arrow's position using the ratio value.

Orientation: BOTTOM
Position: 0.62
showAlignTop
Orientation: TOP
Position : 0.5
showAlignBottom
Orientation: LEFT
Position: 0.5
showAlignRight
Orientation: RIGHT
Position: 0.5
showAlignLeft

Text Composition

We can customize the text on the balloon popup.

.setText("You can edit your profile now!")
.setTextSize(15f)
.setTextTypeface(Typeface.BOLD)
.setTextColor(ContextCompat.getColor(context, R.color.white_87))

If your text has HTML in it, you can enable HTML rendering by adding this:

.setTextIsHtml(true)

This will parse the text using Html.fromHtml(text).

TextForm

TextFrom is an attribute class that has some attributes about TextView for customizing popup text.

TextForm textForm = new TextForm.Builder(context)
  .setText("This is a TextForm")
  .setTextColorResource(R.color.colorPrimary)
  .setTextSize(14f)
  .setTextTypeface(Typeface.BOLD)
  .build();

builder.setTextForm(textForm);

This is how to create TextForm using kotlin dsl.

val form = textForm(context) {
  text = "This is a TextForm"
  textColor = ContextCompat.getColor(context, com.skydoves.balloondemo.R.color.white_87)
  textSize = 14f
  textTypeface = Typeface.BOLD
}

Icon Composition

We can customize the icon on the balloon popup.

.setIconSpace(10) // sets right margin of the icon.
.setIconSize(20) // sets size of the icon.
.setIconDrawable(ContextCompat.getDrawable(context, R.drawable.ic_edit)) // sets a drawable resource.

IconForm

IconForm is an attribute class that has some attributes about ImageView for customizing popup icon.

IconForm iconForm = new IconForm.Builder(context)
  .setDrawable(ContextCompat.getDrawable(context, R.drawable.arrow))
  .setIconColor(ContextCompat.getColor(context, R.color.colorPrimary))
  .setIconSize(20)
  .setIconSpace(12)
  .build();
  
builder.setIconForm(iconForm);

This is how to create IconForm using kotlin dsl.

val form = iconForm(context) {
  drawable = ContextCompat.getDrawable(context, R.drawable.arrow)
  iconColor = ContextCompat.getColor(context, R.color.skyblue)
  iconSize = 20
  iconSpace = 12
}

OnBalloonClickListener, OnBalloonDismissListener, OnBalloonOutsideTouchListener

We can listen to the balloon popup is clicked, dismissed or touched outside using listeners.

balloon.setOnBalloonClickListener(new OnBalloonClickListener() {
  @Override
  public void onBalloonClick() {
    // doSomething;
  }
});
    
balloon.setOnBalloonDismissListener(new OnBalloonDismissListener() {
  @Override
  public void onBalloonDismiss() {
    // doSomething;
  }
});

balloon.setOnBalloonOutsideTouchListener(new OnBalloonOutsideTouchListener() {
  @Override
  public void onBalloonOutsideTouch() {
    // doSomething;
  }
});

We can simplify it using kotlin.

.setOnBalloonClickListener { Toast.makeText(context, "clicked", Toast.LENGTH_SHORT).show() }
.setOnBalloonDismissListener { Toast.makeText(context, "dismissed", Toast.LENGTH_SHORT).show() }
.setOnBalloonOutsideTouchListener { Toast.makeText(context, "touched outside", Toast.LENGTH_SHORT).show() }

Customized layout

We can fully customize the balloon layout using below method.

.setLayout(R.layout.my_balloon_layout)

This is an example of implementing custom balloon popup.

Firstly create an xml layout file like layout_custom_profile on your taste.

val balloon = Balloon.Builder(context)
      .setLayout(R.layout.layout_custom_profile)
      .setArrowSize(10)
      .setArrowOrientation(ArrowOrientation.TOP)
      .setArrowPosition(0.5f)
      .setWidthRatio(0.55f)
      .setHeight(250)
      .setCornerRadius(4f)
      .setBackgroundColor(ContextCompat.getColor(this, R.color.black))
      .setBalloonAnimation(BalloonAnimation.CIRCULAR)
      .setLifecycleOwner(lifecycleOwner)
      .build()

And next we can get the inflated custom layout using getContentView method.

val button: Button = 
  balloon.getContentView().findViewById(R.id.button_edit)
button.setOnClickListener {
  Toast.makeText(context, "Edit", Toast.LENGTH_SHORT).show()
  balloon.dismiss()
}

Persistence

If you want to show-up the balloon popup only once or a specific number of times, here is how to implement it simply.

.setPreferenceName("MyBalloon") // sets preference name of the Balloon.
.setShowCounts(3) // show-up three of times the popup. the default value is 1.
.runIfReachedShowCounts {
  // do something after the preference showing counts is reached the goal.
}

But you can implement it more variously using Only.

only("introPopup", times = 3) {
  onDo { balloon.showAlignTop(anchor) }
}

Avoid Memory leak

Dialog, PopupWindow and etc.. have memory leak issue if not dismissed before activity or fragment are destroyed.
But Lifecycles are now integrated with the Support Library since Architecture Components 1.0 Stable released.
So we can solve the memory leak issue so easily.

Just use setLifecycleOwner method. Then dismiss method will be called automatically before activity or fragment would be destroyed.

.setLifecycleOwner(lifecycleOwner)

Lazy initialization

We can initialize the balloon property lazily using balloon keyword and Balloon.Factory abstract class.
The balloon extension keyword can be used on Activity, Fragment, and View.

Before
CustomActivity.kt

class CustomActivity : AppCompatActivity() {
  private val profileBalloon by lazy { BalloonUtils.getProfileBalloon(context = this, lifecycleOwner = this) }

  // ...
}

After
CustomActivity.kt

class CustomActivity : AppCompatActivity() {
  private val profileBalloon by balloon<ProfileBalloonFactory>()

  // ...
}

We should create a class which extends Balloon.Factory.
An implementation class of the factory must have a default(non-argument) constructor.

ProfileBalloonFactory.kt

class ProfileBalloonFactory : Balloon.Factory() {

  override fun create(context: Context, lifecycle: LifecycleOwner): Balloon {
    return createBalloon(context) {
      setLayout(R.layout.layout_custom_profile)
      setArrowSize(10)
      setArrowOrientation(ArrowOrientation.TOP)
      setArrowPosition(0.5f)
      setWidthRatio(0.55f)
      setHeight(250)
      setCornerRadius(4f)
      setBackgroundColor(ContextCompat.getColor(context, R.color.background900))
      setBalloonAnimation(BalloonAnimation.CIRCULAR)
      setLifecycleOwner(lifecycle)
    }
  }
}

BalloonOverlay

We can show an overlay window over the whole screen except an anchor view.

.setIsVisibleOverlay(true) // sets the visibility of the overlay for highlighting an anchor.
.setOverlayColorResource(R.color.overlay) // background color of the overlay using a color resource.
.setOverlayPadding(6f) // sets a padding value of the overlay shape internally.
.setBalloonOverlayAnimation(BalloonOverlayAnimation.FADE) // default is fade.
.setDismissWhenOverlayClicked(false) // disable dismissing the balloon when the overlay is clicked.

We can change the shape of the highlighting using .setOverlayShape.

.setOverlayShape(BalloonOverlayOval) // default shape
.setOverlayShape(BalloonOverlayRect)
.setOverlayShape(BalloonOverlayCircle(radius = 36f))
.setOverlayShape(BalloonOverlayRoundRect(12f, 12f))
OVAL CIRCLE RECT ROUNDRECT

And we can set the specific position of the overlay shape using the below method.

.setOverlayPosition(Point(x, y)) // sets a specific position of the overlay shape.

BalloonAnimation

We can implement popup animations when showing and dismissing.

BalloonAnimation.NONE
BalloonAnimation.FADE
BalloonAnimation.OVERSHOOT
BalloonAnimation.ELASTIC
BalloonAnimation.CIRCULAR
FADE OVERSHOOT ELASTIC CIRCULAR

Balloon builder methods

We can reference all kinds and descriptions of functions details here.

.setWidth(value: Int)
.setWidthRatio(@FloatRange(from = 0.0, to = 1.0) value: Float)
.setHeight(value: Int)
.setSize(value: Int, value: Int)
.setSpace(value: Int)
.setPadding(value: Int)
.setPaddingLeft(value: Int)
.setPaddingTop(value: Int)
.setPaddingRight(value: Int)
.setPaddingBottom(value: Int)
.setMargin(value: Int)
.setMarginLeft(value: Int)
.setMarginTop(value: Int)
.setMarginRight(value: Int)
.setMarginBottom(value: Int)
.setElevation(value: Int)
.setIsVisibleArrow(value: Boolean)
.setArrowSize(value: Int)
.setArrowPosition(@FloatRange(from = 0.0, to = 1.0) value: Float)
.setArrowOrientation(value: ArrowOrientation)
.setArrowPositionRules(ArrowPositionRules.ALIGN_ANCHOR)
.setArrowColor(value: Int)
.setArrowColorResource(@ColorRes value: Int)
.setArrowDrawable(value: Drawable?)
.setArrowDrawableResource(@DrawableRes value: Int)
.setArrowAlignAnchorPadding(value: Int)
.setArrowAlignAnchorPaddingRatio(value: Float)
.setBackgroundColor(value: Int)
.setBackgroundColorResource(@ColorRes value: Int)
.setBackgroundDrawable(value: Drawable?)
.setBackgroundDrawableResource(@DrawableRes value: Int)
.setCornerRadius(value: Float)
.setText(value: String)
.setTextResource(value: Int)
.setTextColor(value: Int)
.setTextColorResource(value: Int)
.setTextSize(value: Float)
.setTextTypeface(value: Int)
.setTextGravity(value: Int)
.setTextForm(value: TextForm)
.setIconDrawable(value: Drawable?)
.setIconDrawableResource(@DrawableRes value: Int)
.setIconSize(value: Int)
.setIconWidth(value: Int)
.setIconHeight(value: Int)
.setIconColor(value: Int)
.setIconColorResource(@ColorRes value: Int)
.setIconSpace(value: Int)
.setIconForm(value: IconForm)
.setIconGravity(value: IconGravity)
.setAlpha(@FloatRange(from = 0.0, to = 1.0) value: Float)
.setLayout(@LayoutRes layout: Int)
.setIsVisibleOverlay(value: Boolean)
.setOverlayColor(@ColorInt value: Int)
.setOverlayColorResource(@ColorRes value: Int)
.setOverlayPadding(@Dp value: Float)
.setOverlayPosition(value: Point)
.setOverlayShape(value: BalloonOverlayShape)
.setPreferenceName(value: String)
.setShowCount(value: Int)
.isRtlSupport(value: Boolean)
.setFocusable(value: Boolean)
.setLifecycleOwner(value: LifecycleOwner)
.setDismissWhenClicked(value: Boolean)
.setDismissWhenLifecycleOnPause(value: Boolean)
.setDismissWhenTouchOutside(value: Boolean)
.setDismissWhenShowAgain(value: Boolean)
.setDismissWhenOverlayClicked(value: Boolean)
.setBalloonAnimation(value: BalloonAnimation)
.setOnBalloonClickListener(value: OnBalloonClickListener)
.setOnBalloonDismissListener(value: OnBalloonDismissListener)
.setOnBalloonInitializedListener(value: OnBalloonInitializedListener)
.setOnBalloonOutsideTouchListener(value: OnBalloonOutsideTouchListener)
.setOnBalloonOverlayClickListener(value: OnBalloonOverlayClickListener)
.setDismissWhenTouchOutside(value: Boolean)

Find this library useful? ❀️

Support it by joining stargazers for this repository. ⭐

License

Copyright 2019 skydoves (Jaewoong Eum)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Balloon does not adapt to the height of a custom View

    Balloon does not adapt to the height of a custom View

    Please complete the following information:

    • Library version: com.github.skydoves:balloon:1.2.7
    • Affected Device: Samsung Galaxy s9 with Android 9.0

    Describe the Bug:

    We have implemented Balloon with a custom layout. Although the height has specified, some of the text will be cut out if the user adjusts the system font-size.

    Code: https://github.com/wikimedia/apps-android-wikipedia/blob/22b07cdefc8fd184601ae657a2b01dcefd31ed57/app/src/main/java/org/wikipedia/util/FeedbackUtil.java#L226-L234

    Expected Behavior: The library adapts the height of the custom view automatically.

    I have checked https://github.com/skydoves/Balloon/issues/112 but it does not work for me.

    Released 
    opened by cooltey 22
  • ClassCastException: android.widget.RelativeLayout cannot be cast to android.widget.FrameLayout

    ClassCastException: android.widget.RelativeLayout cannot be cast to android.widget.FrameLayout

    • Library-Version - 1.2.5
    • Affected Device(s) Google Pixel 2XL OS - Android 11

    The crash occurs when casting this,

    java.lang.ClassCastException: android.widget.RelativeLayout cannot be cast to android.widget.FrameLayout at com.skydoves.balloon.databinding.LayoutBalloonBinding.bind(LayoutBalloonBinding.java:82) at com.skydoves.balloon.databinding.LayoutBalloonBinding.inflate(LayoutBalloonBinding.java:73) at com.skydoves.balloon.Balloon.(Balloon.kt:97) at com.skydoves.balloon.Balloon$Builder.build(Balloon.kt:1677)

    Material Version Used - 1.1.0 LifeCycle Version - 2.3.0-beta01

    I was using 1.1.9 before this. After updating to 1.2.0+ versions the above crash appears

    bug Released 
    opened by MujammilAhamed 19
  • balloon content always has radius..

    balloon content always has radius..

    happened in Latest version

    just create a list as balloon content ,then add android:background="?attr/selectableItemBackground" on list item for click background status

    however, when i click first item or last item ..radius limit ripple background

    that not expected .. only wanna radius on balloon not for content

    bug Released 
    opened by asker517 15
  • Width of the balloon with a custom layout not adjusted properly when setting text dynamically

    Width of the balloon with a custom layout not adjusted properly when setting text dynamically

    Please complete the following information:

    • Library Version 1.3.1+
    • Affected Device(s) All devices, in particular, Pixel 3a API 28

    Describe the Bug: We are using Balloon.Factory() with a custom layout resource that includes several textViews. After setting text values dynamically, the width of the balloon is not resized to wrap its content (it is fixed with the initial value). As a result, the height of the content increases. The solution provided in #91 cannot be used anymore, since method measureTextWidth is private now. The issue can be easily reproduced using the demo application:

    Step 1 - Add id to the TextView in the layout_custom_tag.xml:

      <TextView
        android:id="@+id/tagTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="12"
        android:textColor="@android:color/black"
        android:textSize="16sp"
        android:textStyle="bold"
        tools:ignore="HardcodedText" />
    

    Step 2 - change the text of that tagTextView to a different value, i.e.:

    customTagBalloon.getContentView().findViewById<TextView>(R.id.tagTextView).text = "Long text"
    

    Step 3 - launch the application and click on the bottomNavBar. As a result, the height of the balloon increased, instead of the width. However, it works properly on version 1.3.0 of the library. Modified demo app to reproduce the issue is also available at: https://github.com/wkubaty/Balloon/tree/custom-layout-size-issue

    Unexpected behavior on version 1.3.4:

    Zrzut ekranu 2021-05-25 o 14 47 00

    Expected Behavior: The width of the balloon with a custom layout should be adjusted properly when setting content dynamically.

    Proper behavior on version 1.3.0:

    Zrzut ekranu 2021-05-25 o 14 48 45 Released 
    opened by wkubaty 14
  • Balloon does not adapt to the height of a custom View on certain devices

    Balloon does not adapt to the height of a custom View on certain devices

    Please complete the following information:

    • Library Version 1.3.3
    • Affected Device(s) Pixel 3 XL with Android 11 and Pixel 2 with Android 10

    Describe the Bug:

    Addressed here: https://github.com/skydoves/Balloon/issues/148#issuecomment-805262834

    The previous fix works fine on Samsung S9 with Android 10, but not on Pixel 3 XL and Pixel 2 and possibly some other devices.

    Expected Behavior:

    Content should not be cutoff.

    bug Released 
    opened by cooltey 13
  • Fatal Exception: java.lang.IllegalStateException

    Fatal Exception: java.lang.IllegalStateException

    Please complete the following information:

    • Library Version 1.2.9
    • Affected Device(s) Samsung, Xiaomi, HUAWEI, OPPO OS 8,9,10

    The Bug:

    I'm using only showAlignTop method, but in some cases this crash is popping on my Firebase Crashlytics.

    The specified child already has a parent. You must call removeView() on the child's parent first.

    Fatal Exception: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
           at android.view.ViewGroup.addViewInner(ViewGroup.java:5106)
           at android.view.ViewGroup.addView(ViewGroup.java:4935)
           at android.view.ViewGroup.addView(ViewGroup.java:4907)
           at android.widget.PopupWindow.createBackgroundView(PopupWindow.java:1530)
           at android.widget.PopupWindow.preparePopup(PopupWindow.java:1492)
           at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:1417)
           at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:1380)
           at com.skydoves.balloon.Balloon$showAlignTop$$inlined$show$1.run(Balloon.java:1774)
           at android.os.Handler.handleCallback(Handler.java:883)
           at android.os.Handler.dispatchMessage(Handler.java:100)
           at android.os.Looper.loop(Looper.java:214)
           at android.app.ActivityThread.main(ActivityThread.java:7403)
           at java.lang.reflect.Method.invoke(Method.java)
           at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
    

    Possible solution:

    Was not able to full reproduce yet, but maybe we can find the right part of the library and to some parent check, like

    if(tv.getParent() != null) {
        ((ViewGroup)tv.getParent()).removeView(tv); // <- fix
    }
    layout.addView(tv);
    
    Released 
    opened by Canato 13
  • Balloon crashes on showing, BadTokenException

    Balloon crashes on showing, BadTokenException

    We are using the newest Balloon version 1.1.5 in our app.

    I just saw a crash in crashlytics and cannot reproduce it on my own, but it occurred 9 times until now.

    Android-Versions: no specific version

    Stacktrace: Fatal Exception: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running? at android.view.ViewRootImpl.setView(ViewRootImpl.java:1122) at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:450) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:95) at android.widget.PopupWindow.invokePopup(PopupWindow.java:1621) at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:1456) at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:1412) at com.skydoves.balloon.Balloon$showAlignBottom$$inlined$show$2.run(Balloon.java:970) at android.os.Handler.handleCallback(Handler.java:883) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:237) at android.app.ActivityThread.main(ActivityThread.java:8016) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1076) at com.android.internal.os.Device.fp(Device.java)

    Could you at least catch this exception, so it won't crash the app? Thank you very much!

    opened by dpeters-ipc 13
  • Unable to build balloon object

    Unable to build balloon object

    Please complete the following information:

    • Library Version [e.g. v1.2..3]
    • Affected Device(s) [e.g. One Plus 6 Android 10, Nexus S Android 8 Emulator]

    Describe the Bug:

    Add a clear description about the problem. On tap of an icon i want to show tooltip but on build I am getting: java.lang.NullPointerException: Missing required view with ID: balloon Expected Behavior:

    A clear description of what you expected to happen: I want to show the tooltip

    opened by dduvedi 12
  • Bug setWidth(BalloonSizeSpec.WRAP) v 1.4.5

    Bug setWidth(BalloonSizeSpec.WRAP) v 1.4.5

    • Library Version 1.4.5
    • Affected Device(s) All devices

    I have a custom view that I use with balloon, the width WRAP not working correctly. I am displaying the view in a item from tabLayout. I tried using the container linearLayout, relativeLayout and constraintLayout but I can't get it to fit the content. The width of the textView are dynamic. The only way for the width to change is by setting it to a fixed value

    tabLayout.getTabAt(TAB_NOTIFICATIONS_POSITION)?.view?.let { val nUnreadLikes = 100L val nUnreadComments = 1232L val nUnreadFollowers = 12000L Balloon.Builder(it.context) .setLayout(R.layout.popup_window_notifications) .setArrowOrientation(ArrowOrientation.TOP) .setArrowPosition(0.5f) .setHeight(BalloonSizeSpec.WRAP) .setWidth(BalloonSizeSpec.WRAP) .setCornerRadius(4f) .setArrowColorMatchBalloon(true) .setBackgroundDrawable(ContextCompat.getDrawable(it.context, R.drawable.bg_popup_window_notification)) .setBalloonAnimation(BalloonAnimation.FADE) .setLifecycleOwner(lifecycleOwner) .setAutoDismissDuration(4000) .setOnBalloonInitializedListener { view -> val tvLikes = view.findViewById(R.id.tvLikes) val tvComments = view.findViewById(R.id.tvComments) val tvFollowers = view.findViewById(R.id.tvFollowers) nUnreadLikes.let { tvLikes?.text = it.abbreviateNumber() } nUnreadComments.let { tvComments?.text = it.abbreviateNumber() } nUnreadFollowers.let { tvFollowers?.text = it.abbreviateNumber() } }.build().showAlignTop(it)

    XML resource

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/tvLikes"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawablePadding="4dp"
        android:textColor="@color/White"
        android:fontFamily="@font/lato_medium"
        android:textSize="13sp"
        android:maxLines="1"
        android:paddingEnd="16dp"
        android:paddingStart="0dp"
        android:layout_alignParentStart="true"
        app:drawableStartCompat="@drawable/ic_heart_notifications"
        tools:text="100" />
    
    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/tvComments"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawablePadding="4dp"
        android:textColor="@color/White"
        android:fontFamily="@font/lato_medium"
        android:textSize="13sp"
        android:maxLines="1"
        android:layout_toEndOf="@+id/tvLikes"
        app:drawableStartCompat="@drawable/ic_comments_notifications"
        android:paddingEnd="16dp"
        android:paddingStart="0dp"
        tools:text="1.232" />
    
    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/tvFollowers"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawablePadding="4dp"
        android:textColor="@color/White"
        android:fontFamily="@font/lato_medium"
        android:textSize="13sp"
        android:layout_toEndOf="@+id/tvComments"
        android:maxLines="1"
        app:drawableStartCompat="@drawable/ic_profile_notifications"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintStart_toEndOf="@+id/tvComments"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="12K" />
    

    Parent container RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp"

    Current Captura de Pantalla 2022-05-04 a la(s) 16 57 49

    Expected Captura de Pantalla 2022-05-04 a la(s) 16 59 37

    Please help me! thank you!

    opened by gonzalomonzon02 11
  • App crash when calling showAlignBottom

    App crash when calling showAlignBottom

    • Affected Device(s) [Android 11,10,9,8]

    Fatal Exception: java.lang.NullPointerException Attempt to read from field 'int android.view.ViewGroup$LayoutParams.width' on a null object reference

    com.skydoves.balloon.Balloon$showAlignBottom$$inlined$show$1.run Same code working great with showAlignTop

    If you want I can share Firebase Crashlytics logs.

    Piyush Sinha Testbook.com

    Released 
    opened by PiyushSinha-tb 11
  • After Dismiss First Popup Another is Not Open without Second Time Click

    After Dismiss First Popup Another is Not Open without Second Time Click

    Please complete the following information:

    • Library Version [e.g. v1.2.6]
    • Affected Device(s) [e.g. Samsung Galaxy J7 Pro with Android 9.0]

    Describe the Bug:

    • I used This Lib in Bottom Navigation.when I click on any bottom navigation Tab it is open.when I click on second tab first popup dismiss but not open second one.After Click Second Time New PopUp open.please help me for same. BottomPopUP

    Expected Behavior: -I want when i click on tab that particular tab popup open and old one dismiss if it is open.

    opened by shreyushah 11
  • A11y fix: remove clickable hint from Talkback description when no click listener is set on Balloon

    A11y fix: remove clickable hint from Talkback description when no click listener is set on Balloon

    🎯 Goal

    The goal of this PR is to improve the correctness of screen reader hints for Balloons that do not have a click listener set (via Balloon::setOnBalloonClickListener).

    Currently, Talkback will incorrectly say "double-tap to activate" for these Balloons. This change removes that part of the Talkback description without affecting the rest of it.

    πŸ›  Implementation details

    Currently setOnBalloonClickListener() always sets a "wrapper/parent" click listener on the Balloon, even when the click listener argument is null. Talkback incorrectly infers from this that the Balloon is clickable, despite it possibly being a no-op click listener.

    This change only sets the parent click listener when clicking would likely have some noticeable effect. More specifically, if the onBalloonClickListener argument is non-null or if builder.dismissWhenClicked is true.

    android:focusable="true" was set on the balloon wrapper FrameLayout in order to maintain the existing Talkback behavior of reading out the text contents of the Balloon.

    ✍️ Explain examples

    In the example below, tapping the highlighted balloon with Talkback on would currently read out: "skydoves. Love coffee, music, magic tricks and writing poems. Double-tap to activate."

    After this change: "skydoves. Love coffee, music, magic tricks and writing poems."

    Preparing a pull request for review

    Ensure your change is properly formatted by running:

    $ ./gradlew spotlessApply
    

    βœ…

    Please let me know if you have any requests for improvement for this to be acceptable to merge.

    opened by matt-clarke-wooliesx 0
  • Unable to show custom layout

    Unable to show custom layout

    Please complete the following information:

    • Library Version v1.4.8
    • Affected Device(s) [RedMi 9A - Android 10]

    Describe the Bug:

    I try to add the custom layout but it shown black screen and doesn't load my custom layout.

    Expected Behavior:

    Custom layout should be shown in the tooltip.

    My Code:

    class CustomBalloon : Balloon.Factory() {
        override fun create(context: Context, lifecycle: LifecycleOwner?): Balloon {
            return createBalloon(context) {
                    setLayout(R.layout.company_registeration)
                    .setArrowSize(10)
                    .setArrowOrientation(ArrowOrientation.TOP)
                    .setArrowPosition(0.5f)
                    .setWidthRatio(0.55f)
                    .setHeight(250)
                    .setCornerRadius(4f)
                    .setBackgroundColor(ContextCompat.getColor(context, R.color.black))
                    .setBalloonAnimation(BalloonAnimation.CIRCULAR)
                    .setLifecycleOwner(lifecycleOwner)
                    .build()
            }
        }
    }
    

    Expected Result (my custom layout xml):

    Screenshot 2022-12-25 at 7 59 53 PM

    Current Behaviour: Screenshot 2022-12-25 at 7 59 08 PM

    opened by shahwaiz90 1
  • Sequential balloons with ability to go back and forth, and to show more then one View as highlighted

    Sequential balloons with ability to go back and forth, and to show more then one View as highlighted

    As a developer I would like to be able to use the lib to display an intro for the app first user, where I highlight different parts of home page. I would like to seamlessly go between highlighting different components (without showing the Home Screen in between highlights) and would like the ability for user to go back to previous balloon. I also would like the ability to highlight multiple components simultaneously. I tried managing myself and not using the relay (because with relay can't highlight more then one item, and can't go back), but between dismissing one ballon and showing next the Home Screen flashes and does not look good. Any ideas or recommendations would be appreciated.

    opened by chaimgross 0
  •     android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRootImpl$W@8722970 is not valid; is your activity running?

    android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRootImpl$W@8722970 is not valid; is your activity running?

    Please complete the following information:

    • Library Version [1.4.7]
    • Affected Device(s) [All]

    Describe the Bug:

    Open PopupWindow (My) Make it child view anchor for Balloon And show balloon

    Expected Behavior:

    "Balloon pop up" must be shown, but application crashed

    android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRootImpl$W@82e619c is not valid; is your activity running? at android.view.ViewRootImpl.setView(ViewRootImpl.java:1593) at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:509) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:133) at android.widget.PopupWindow.invokePopup(PopupWindow.java:1688) at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1408) at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1374) at com.skydoves.balloon.Balloon.showOverlayWindow(Balloon.kt:812) at com.skydoves.balloon.Balloon.access$showOverlayWindow(Balloon.kt:143) at com.skydoves.balloon.Balloon$showAlign$$inlined$show$1.run(Balloon.kt:777) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:226) at android.os.Looper.loop(Looper.java:313) at android.app.ActivityThread.main(ActivityThread.java:8663) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

    opened by Arm63 11
  • Initialize arrow crashes while trying to get the color from the balloon

    Initialize arrow crashes while trying to get the color from the balloon

    Please complete the following information:

    • Library Version: 1.4.5
    image

    Hello @skydoves, our app with Balloon version 1.4.5 suffers from a crash that occurs when the app is in background. I could not reproduce the error, do you have any idea why would this happen and how could we fix this crash?

    opened by ozaneb 6
  • Arrow unable to reach the edge with ArrowPositionRules.ALIGN_ANCHOR

    Arrow unable to reach the edge with ArrowPositionRules.ALIGN_ANCHOR

    Please complete the following information:

    • Library Version [e.g. v1.4.7]
    • Affected Device(s) [OnePlus 6T with Android 11, OnePlus 8T with Android 12]

    Describe the Bug: Issue 1 When using ArrowPositionRules.ALIGN_ANCHOR, the arrow cannot get close to the edge of the ballon with setArrowPosition(1f) or setArrowPosition(0f).

    Issue 2 When using ArrowPositionRules.ALIGN_ANCHOR, the left and right padding aren't even with setArrowPosition(1f) and setArrowPosition(0f).

    Screenshot_20220907-181117

    Expected Behavior:

    1. Have an anchor view with layout_width="match_parent"
    2. Create a balloon with setArrowPositionRules(ArrowPositionRules.ALIGN_ANCHOR) and setArrowPosition(0f)
    3. Show the balloon using showAlignTop() and position it at the left more edge

    Expect: the arrow should be very close to the edge of the balloon. Actual: the is a large space between the arrow and the edge of the balloon.

    Please see https://github.com/GC-Xi/ArrowPosition as example.

    opened by GC-Xi 2
Releases(1.5.2)
  • 1.5.2(Jan 7, 2023)

    What's Changed

    • Fixed Compose balloon content measurement systems with density by @skydoves in https://github.com/skydoves/Balloon/pull/403

    Full Changelog: https://github.com/skydoves/Balloon/compare/1.5.1...1.5.2

    Source code(tar.gz)
    Source code(zip)
  • 1.5.1(Jan 6, 2023)

    What's Changed

    • Update anchor view's size with onSizeChanged by @skydoves in https://github.com/skydoves/Balloon/pull/400
    • Refactor measuring ways for the width composable content size by @skydoves in https://github.com/skydoves/Balloon/pull/401
    • Add rules for the start and end arrow position of ALIGN_ANCHOR by @skydoves in https://github.com/skydoves/Balloon/pull/402
    • Fix README typo by @vagabond95 in https://github.com/skydoves/Balloon/pull/398

    New Contributors

    • @vagabond95 made their first contribution in https://github.com/skydoves/Balloon/pull/398

    Full Changelog: https://github.com/skydoves/Balloon/compare/1.5.0...1.5.1

    Source code(tar.gz)
    Source code(zip)
  • 1.5.0(Jan 2, 2023)

    What's Changed

    • Introduced balloon-compose package. Check out the Balloon in Jetpack Compose.
    • Update baseline profiles by @skydoves in https://github.com/skydoves/Balloon/pull/389
    • Change iconContentDescription type to CharSequence by @skydoves in https://github.com/skydoves/Balloon/pull/390
    • Introduce version catalog and migrate gradle files to kts by @skydoves in https://github.com/skydoves/Balloon/pull/391
    • Introduce balloon-compose module by @skydoves in https://github.com/skydoves/Balloon/pull/393
    • Update baseline profiles for balloon by @skydoves in https://github.com/skydoves/Balloon/pull/394
    • Update baseline profiles for balloon compose by @skydoves in https://github.com/skydoves/Balloon/pull/395
    • Update README for Jetpack Compose by @skydoves in https://github.com/skydoves/Balloon/pull/396

    Full Changelog: https://github.com/skydoves/Balloon/compare/1.4.8...1.5.0

    Source code(tar.gz)
    Source code(zip)
  • 1.4.8(Dec 16, 2022)

    What's Changed

    • Implement the getArrowForeground and refactor the setting foreground by @skydoves in https://github.com/skydoves/Balloon/pull/367
    • Update AGP to 7.3.0 and target SDK to 33 by @skydoves in https://github.com/skydoves/Balloon/pull/368
    • Update Kotlin to 1.7.20 and other androidx dependencies by @skydoves in https://github.com/skydoves/Balloon/pull/369
    • Fix getting resource id from the drawable tint color by @skydoves in https://github.com/skydoves/Balloon/pull/374
    • Update Kotlin to 1.7.21 and gradle to 7.6 by @skydoves in https://github.com/skydoves/Balloon/pull/385
    • Implement runOnAfterSDK23 and fix lint errors by @skydoves in https://github.com/skydoves/Balloon/pull/386
    • Allow setting text lineSpacing Extra by @skydoves in https://github.com/skydoves/Balloon/pull/387
    • Allow setting ContentDescription for the balloon icon by @skydoves in https://github.com/skydoves/Balloon/pull/388

    Full Changelog: https://github.com/skydoves/Balloon/compare/1.4.7...1.4.8

    Source code(tar.gz)
    Source code(zip)
  • 1.4.7(Aug 6, 2022)

    What's Changed

    • Add the possibility to change overlay window gravity (#347) by @skydoves in https://github.com/skydoves/Balloon/pull/349
    • Update AGP and dependencies version by @skydoves in https://github.com/skydoves/Balloon/pull/350
    • Replace AppCompatImageView to ImageView for the arrow by @skydoves in https://github.com/skydoves/Balloon/pull/355
    • Check API level with isAPILevelHigherThan23 before setting foreground the arrow by @skydoves in https://github.com/skydoves/Balloon/pull/356

    Full Changelog: https://github.com/skydoves/Balloon/compare/1.4.6...1.4.7

    Source code(tar.gz)
    Source code(zip)
  • 1.4.6(Jun 30, 2022)

    🎈 A new version 1.4.6 was released! 🎈

    What's Changed

    • Update buildSrc package name by @skydoves in https://github.com/skydoves/Balloon/pull/329
    • Move definitions into the internal package by @skydoves in https://github.com/skydoves/Balloon/pull/330
    • Remove the registered observer on onDestroy lifecycle by @skydoves in https://github.com/skydoves/Balloon/pull/333
    • Remove deprecated Left and Right arrow orientations by @skydoves in https://github.com/skydoves/Balloon/pull/334
    • Add spotless rules for XML formats by @skydoves in https://github.com/skydoves/Balloon/pull/336
    • Bump AGP to 7.2.0 and kotlin to 1.6.21 by @skydoves in https://github.com/skydoves/Balloon/pull/338
    • Update compile and target SDK to 32 by @skydoves in https://github.com/skydoves/Balloon/pull/342
    • Improve library performance using Baseline Profiles by @skydoves in https://github.com/skydoves/Balloon/pull/344
    • Implement BalloonOverlayEmpty by @skydoves in https://github.com/skydoves/Balloon/pull/345
    • Bump Kotlin to 1.7.0 by @skydoves in https://github.com/skydoves/Balloon/pull/346

    Full Changelog: https://github.com/skydoves/Balloon/compare/1.4.5...1.4.6

    Source code(tar.gz)
    Source code(zip)
  • 1.4.5(Apr 30, 2022)

    🎈 Released a new version 1.4.5! 🎈

    What's Changed

    • Set nonTransitiveRClass property as true by @skydoves in https://github.com/skydoves/Balloon/pull/324
    • Configure Gradle environments by @skydoves in https://github.com/skydoves/Balloon/pull/325
    • Add public.xml to the resources by @skydoves in https://github.com/skydoves/Balloon/pull/327
    • Add publishing DSL with singleVariant by @skydoves in https://github.com/skydoves/Balloon/pull/328

    Full Changelog: https://github.com/skydoves/Balloon/compare/1.4.4...1.4.5

    Source code(tar.gz)
    Source code(zip)
  • 1.4.4(Apr 4, 2022)

    🎈 Balloon 1.4.4 has been released! 🎈

    What's Changed

    • Bump Gradle Wrapper to 7.4.2 by @skydoves in https://github.com/skydoves/Balloon/pull/320
    • Migrate maven publish process by @skydoves in https://github.com/skydoves/Balloon/pull/319
    • Cleanup Gradle properties by @skydoves in https://github.com/skydoves/Balloon/pull/321

    Full Changelog: https://github.com/skydoves/Balloon/compare/1.4.3...1.4.4

    Source code(tar.gz)
    Source code(zip)
  • 1.4.3(Mar 26, 2022)

    🎈 Balloon 1.4.3 has been released! 🎈

    What's Changed

    • Bump Kotlin to 1.5.32 by @skydoves in https://github.com/skydoves/Balloon/pull/308
    • Update README.md by @suman-somu in https://github.com/skydoves/Balloon/pull/311
    • Use srcCompat on the balloon_layout_body layout by @skydoves in https://github.com/skydoves/Balloon/pull/312
    • update the version of gradleBuildTool from 7.1.0 to 7.1.2 by @jadenkor in https://github.com/skydoves/Balloon/pull/313
    • Implement multiple overlay views by @skydoves in https://github.com/skydoves/Balloon/pull/314
    • Bump maven and spotless versions by @skydoves in https://github.com/skydoves/Balloon/pull/315
    • New Feature: showAlign method and extension by @skydoves in https://github.com/skydoves/Balloon/pull/316
    • Support RTL layout for the arrow orientation by @skydoves in https://github.com/skydoves/Balloon/pull/317

    New Contributors

    • @suman-somu made their first contribution in https://github.com/skydoves/Balloon/pull/311
    • @jadenkor made their first contribution in https://github.com/skydoves/Balloon/pull/313

    Full Changelog: https://github.com/skydoves/Balloon/compare/1.4.2...1.4.3

    Source code(tar.gz)
    Source code(zip)
  • 1.4.2(Feb 14, 2022)

    🎈 Balloon 1.4.2 has been released! 🎈

    What's Changed

    • Add resource prefix and modify resources name by @skydoves in https://github.com/skydoves/Balloon/pull/291
    • Implement setLayout method with ViewBinding by @skydoves in https://github.com/skydoves/Balloon/pull/293
    • Remove deprecated functions since 1.3.8 by @skydoves in https://github.com/skydoves/Balloon/pull/300
    • Implement balloon extension for ViewBinding to initialize lazy property by @skydoves in https://github.com/skydoves/Balloon/pull/301
    • Bump kotlin to 1.5.31 by @skydoves in https://github.com/skydoves/Balloon/pull/302
    • Rectified Issue #298 by @itsnitish22 in https://github.com/skydoves/Balloon/pull/303
    • Refactor AppCompat TextView and ImageView by @skydoves in https://github.com/skydoves/Balloon/pull/305
    • Improved README by @skydoves in https://github.com/skydoves/Balloon/pull/292
    • Update README.md by @itsnitish22 in https://github.com/skydoves/Balloon/pull/296

    New Contributors

    • @itsnitish22 made their first contribution in https://github.com/skydoves/Balloon/pull/296

    Full Changelog: https://github.com/skydoves/Balloon/compare/1.4.1...1.4.2

    Source code(tar.gz)
    Source code(zip)
  • 1.4.1(Dec 19, 2021)

    🎈 Balloon 1.4.1 has been released! 🎈

    What's Changed

    • Feature: Migrate to lifecycle 2.4.0 by @skydoves in https://github.com/skydoves/Balloon/pull/277
    • Apply explicit mode by @skydoves in https://github.com/skydoves/Balloon/pull/278
    • Add androidx annotations to check API version by @skydoves in https://github.com/skydoves/Balloon/pull/279
    • Change folder name to kotlin by @skydoves in https://github.com/skydoves/Balloon/pull/282
    • Use a new view property delegate extension by @skydoves in https://github.com/skydoves/Balloon/pull/283
    • Check if the layout has any parent view by @skydoves in https://github.com/skydoves/Balloon/pull/286
    • Check LifecycleOwner by using findViewTreeLifecycleOwner by @skydoves in https://github.com/skydoves/Balloon/pull/287
    • Implement canShowBalloonWindow and check anchor is attached in the post by @skydoves in https://github.com/skydoves/Balloon/pull/284

    Full Changelog: https://github.com/skydoves/Balloon/compare/1.4.0...1.4.1

    Source code(tar.gz)
    Source code(zip)
  • 1.4.0(Oct 29, 2021)

    🎈 Balloon 1.4.0 has been released! 🎈

    What's New?

    • Added: support for passing touch events to the anchor. (#268)
    • Updated: A constructor of the Balloon class changed as private.
    • Updated: Added missing JvmOverloads annotations to Highlight builder methods.
    • Updated: Removed JvmField annotations to expose getters of the Ballon.Builder on Java Side.
    • Updated: Downgrade JVM target to 1.8 of the balloon module. (#273)
    Source code(tar.gz)
    Source code(zip)
  • 1.3.9(Oct 3, 2021)

    🎈 Released a new version 1.3.9! 🎈

    What's New?

    • Added new highlighting animations.

    HEARTBEAT | SHAKE | BREATH | ROTATE | | :---------------: | :---------------: | :---------------: | :---------------: | | | | | |

    BalloonHighlightAnimation

    We can give repeated dynamic animations to Balloon when it's showing.
    The animation would work differently by the position of the arrow.

    BalloonHighlightAnimation.NONE
    BalloonHighlightAnimation.HEARTBEAT
    BalloonHighlightAnimation.SHAKE
    BalloonHighlightAnimation.BREATH
    BalloonHighlightAnimation.ROTATE
    
    .setBalloonHighlightAnimation(BalloonHighlightAnimation.SHAKE)
    
    Source code(tar.gz)
    Source code(zip)
  • 1.3.8(Sep 22, 2021)

    🎈 Released a new version 1.3.8! 🎈

    What's New?

    • New feature: A new showAtCenter() function. We can show up the Balloon over the anchor view align center. (#247). We can align the location of the Balloon using the BalloonCenterAlign parameter.
    anchor.showAtCenter(balloon, xOff = 0, yOff = 0, centerAlign = BalloonCenterAlign.Bottom)
    
    • Deprecated: show() functions have been deprecated now. Use showAtCenter() or showAsDropDown() instead. (#247)
    • Fixed: RadiusLayout clips internal contents with the wrong radius size. (#220, #245)
    • New feature: We can clear every persisted data on the BalloonPersistence via balloon.clearAllPreferences() function. (#242)
    • Modified: We can access BalloonPersistence class: val balloonPersistence = BalloonPersistence.getInstance(context). (#242)
    • Refactored internal codes. (#244, #248)
    Source code(tar.gz)
    Source code(zip)
  • 1.3.7(Sep 11, 2021)

    🎈 Released a new version 1.3.7! 🎈

    What's New?

    • Updated: Now the bodyWindow and overlayWindow properties are accessible from the public.
    • Added: Added a new setIsAttachedInDecor method related #131
    • Fixed: The wrong references were used in getMeasuredTextWidth. (#219)
    • Updated: Making it possible to add color to the overlay padding. (#221)
    • Fixed: Drawing the overlay padding rectangle. (#223)
    • Fixed: Overlay is not redrawn on Balloon.update(anchor) call. (#229)
    • Fixed: min/max ratio inconsistency in getMeasuredTextWidth #226
    • Refactored: Size extensions. (#217)

    Thanks to @JoePaul @vitkhudenko for contributions!

    Source code(tar.gz)
    Source code(zip)
  • 1.3.6(Jul 28, 2021)

    🎈 Released a new version 1.3.6! 🎈

    What's New?

    • Added support for gradient colors on the default arrow(#203)
    • Added onTouchListener option to the overlay popup (#204)
    • Added setOnBalloonOverlayTouchListener using a lambda(#205)
    • Added check to see if balloon should show up (#206)
    • Fixed Auto dismiss (#210) (#211)
    • Added minimum and maximum ratio for the Balloon (#214)
    • Fixed overlay padding units (#212) (#215)
    • Refactor measuring text sizes (#191) (#209)

    Thanks, @DavidJsson @JoePaul

    Source code(tar.gz)
    Source code(zip)
  • 1.3.5(Jul 2, 2021)

    🎈 Released a new version 1.3.5! 🎈

    πŸŽ‰ Balloon has been featured on the official Google Dev library.πŸŽ‰

    What's New?

    • Added: setPaddingHorizontal, setPaddingVertical, setMarginHorizontal, and setMarginVertical functions.
    • Fix: Lint shows error for dimen resource id. (#190)
    • Fix: Move post runner inside of the if conditional and check isAttachedToWindow (#192, #197)
    • Update: Invoke dismiss() instead of the onDestroy() on Pause lifecycle event. (#186)
    • Update: A lot of internal refactoring.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.4(Apr 3, 2021)

    πŸŽ‰ Released a new version 1.3.4! πŸŽ‰

    What's New?

    • Changed required min SDK 16 to 17.
    • Fixed: Balloon.isShowing is not set to false when ShowCounts is reached (#168)
    • Fixed: Balloon does not adapt to the height of a custom View on certain devices (#171)
    • Added: minWidth and maxWidth functions for setting range of the balloon width size. This functionality works only with the BalloonSizeSpec.WRAP].
    • Removed: isRtlSupport function and it will be applied automatically based on the default RTL LayoutDirection by a device.
    • Deprecated: IconGravity.LEFT and IconGravity.RIGHT are deprecated and there are new IconGravity.START and IconGravity.END gravities for RTL supports.
    • Added: getBalloonArrowView() function for getting a view of the balloon arrow. (#180)
    Source code(tar.gz)
    Source code(zip)
  • 1.3.3(Feb 26, 2021)

    πŸŽ‰ Released a new version 1.3.3! πŸŽ‰

    What's New?

    • Fixed: Balloon does not adapt to the height of a custom View (#148)
    • Fixed: arrow visibility does not respect setIsVisibleArrow(false) (#162)
    Source code(tar.gz)
    Source code(zip)
  • 1.3.2(Feb 19, 2021)

    πŸŽ‰ Released a new version 1.3.2! πŸŽ‰

    What's New?

    • Fixed: Arrow not placing the first time at the right position (#155)
    • Fixed: Balloon does not adapt to the height of a custom View (#148)
    • Refactored measuring text size of the balloon for calculating properly width size of the custom layout and the default VectorTextView.
    • Added some function documentations for explaining the purpose of parameters.
    • Removed internal JCenter publishing tasks and migrated to maven central.
    • Migrated androidx.lifecycle:lifecycle-compiler apt to androidx.lifecycle:lifecycle-common-java8 dependency for faster compilation.
    • Uses Java 1.8 compile options since this version.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.1(Jan 28, 2021)

    πŸŽ‰ Released a new version 1.3.1! πŸŽ‰

    What's New?

    • Fixed: Overlay does not position correctly in bottom sheet containers (#141)
    • Changed: balloon extension in the Fragment will not return nullable anymore. (non-nullable, thanks @svrlopatrik)
    • Rename: ArrowConstraints renamed to ArrowPositionRules.
    • Added: ArrowOrientationRules. (reference)
    • Added: BalloonHighlightAnimation for highlighting the balloon with animation. (thanks @svrlopatrik) We can set the highlight animation like the below.
    .setBalloonHighlightAnimation(BalloonHighlightAnimation.HEARTBEAT)
    
    • Added: Balloon's setter functions with dimension resource parameter. (c9a900c, thanks @svrlopatrik)
    • Fixed: Shadow gets cut at the bottom of the tooltip (#150)
    • Fixed: Fatal Exception: java.lang.IllegalStateException (#149)
    • Fixed: Balloon does not adapt to the height of a custom View (#148).
    • Changed: Now we don't need to call the measureTextWidth() for measuring the TextView's exact size. It will be measured automatically.
    • Fixed: Option to switch arrow orientation based on the tooltip position (#122, #147)
    • Fixed: Arrow does not show elevation (#76)
    Source code(tar.gz)
    Source code(zip)
  • 1.3.0(Jan 14, 2021)

    πŸŽ‰ Released a new version 1.3.0! πŸŽ‰

    What's New?

    • Added new methods for the Balloon.Builder.
      • setSize(int width, int height)
      • setSizeResource(int width dimension resource, height dimension resource)
      • setIconWidth(int width), setIconHeight(int width)
    • Now the setLifecycleOwner will be called automatically in the internal logic. (92790dd)
    • Added and removed some methods related to the Persistence.
      • Removed unused methods in the BalloonPersistence.
      • Renamed setShowTime to setShowCounts.
      • Added a new method for the Balloon.Builder, runIfReachedShowCounts. The argument lambda will be invoked after the preference showing counts is reached the goal.
    balloon.runIfReachedShowCounts {
     // do something after reached to show counts.
    }
    
    • Refactored ViewBalloonLazy internally for getting an Activity.
    • Removed the cardview dependency in the balloon module.
    • Refactored internal balloon layout structures.
    • There is an unintended space between the arrow and the message box. (#139)
    Source code(tar.gz)
    Source code(zip)
  • 1.2.9(Dec 25, 2020)

    πŸŽ‰ Released a new version 1.2.9! πŸŽ‰

    What's New?

    • Fixed a balloon popup's shadow getting clipped (#134)

    Added a BalloonSizeSpec (#135)

    A specification interface for determining sizes of the Balloon materials. We can wrap some materials depending on their size of content using this interface.

    .setWidth(BalloonSizeSpec.WRAP)
    .setHeight(BalloonSizeSpec.WRAP)
    .setArrowSize(BalloonSizeSpec.WRAP)
    

    Deprecated previous balloon lazy extension and added new extensions.

    Previous (Deprecated)
    private val customListBalloon by balloon(CustomListBalloonFactory::class)
    
    After
    private val customListBalloon by balloon<CustomListBalloonFactory>()
    
    Source code(tar.gz)
    Source code(zip)
  • 1.2.8(Dec 13, 2020)

    πŸŽ‰ Released a new version 1.2.8! πŸŽ‰

    What's New?

    • Added balloon extension for View class via ViewBalloonLazy. Now we can initialize the Balloon lazily using the Balloon.Factory in custom views.
    • Fixed wrong annotations ColorInt to ColorRes for the setIconColorResource.
    • Fixed setIconColor is not working properly (#130).
    • Renamed isArrowVisible() to isVisibleArrow() and fixed not working properly.
    • The circularReveal extensions are changed to the inline function.
    • Renamed BalloonDsl to BalloonInlineDsl internally.
    Source code(tar.gz)
    Source code(zip)
  • 1.2.7(Dec 1, 2020)

    πŸŽ‰ Released a new version 1.2.7! πŸŽ‰

    What's New?

    • Fixed: Arrow not showing if the parent of an anchor is rtl. (#125)
    • Fixed: Arrow is hidden behind Balloon If fitsSystemWindows` is true in theme styles. (#123)
    • Changed previous anim, drawable, and styles resources convention. (08f9723)
    • Changed previous layout and drawable resources naming convention. (30917cf)
    • Refactor show and relayShow functionalities for receiving xOff and yOff. (b7c9808)
    Source code(tar.gz)
    Source code(zip)
  • 1.2.6(Nov 24, 2020)

    πŸŽ‰ Released a new version 1.2.6! πŸŽ‰

    What's New?

    • Fix setPaddingResource and setMarginResource are applied as double size. (21dee54)
    • Prevent generating the BuildConfig class from the balloon module.
    • Changed visibility of the ActivityBalloonLazy and FragmentBalloonLazy class as internal.
    • Internal refactorings.
    Source code(tar.gz)
    Source code(zip)
  • 1.2.5(Nov 7, 2020)

    πŸŽ‰ Released a new version 1.2.5! πŸŽ‰

    What's New?

    • Hided void return-type setters in the Builders for Java APIs.
    • Migrate deprecated fromHtml to HtmlCompat and move applyIconForm. (f92b4e4)
    • Change isOutsideTouchable is always true of the bodyWindow. (#93)
    • Implement isFinishing() extension and check isFinishing an activity. (#92)
    • Refactor onDestroy and onPause functions by lifecycle events to dismiss. (#92)
    • Updated gradle build tool version to 4.1.0 and wrapper version to 6.6.1 internally.
    Source code(tar.gz)
    Source code(zip)
    balloon-1.2.5.aar(167.10 KB)
  • 1.2.4(Oct 15, 2020)

    πŸŽ‰ Released a new version 1.2.4! πŸŽ‰

    What's New?

    • Added an overlay window for highlighting an anchor view.

    We can show an overlay window over the whole screen except an anchor view.

    .setIsVisibleOverlay(true) // sets the visibility of the overlay for highlighting an anchor.
    .setOverlayColorResource(R.color.overlay) // background color of the overlay using a color resource.
    .setOverlayPadding(6f) // sets a padding value of the overlay shape internally.
    .setBalloonOverlayAnimation(BalloonOverlayAnimation.FADE) // default is fade.
    

    We can change the shape of the highlighting using .setOverlayShape.

    .setOverlayShape(BalloonOverlayOval) // default shape
    .setOverlayShape(BalloonOverlayRect)
    .setOverlayShape(BalloonOverlayCircle(radius = 36f))
    .setOverlayShape(BalloonOverlayRoundRect(12f, 12f))
    

    And we can set the specific position of the overlay shape using the below method.

    .setOverlayPosition(Point(x, y)) // sets a specific position of the overlay shape.
    

    overlay

    Source code(tar.gz)
    Source code(zip)
    balloon-1.2.4.aar(167.06 KB)
  • 1.2.3(Sep 10, 2020)

    πŸŽ‰ Released a new version 1.2.3! πŸŽ‰

    What's New?

    • Used JvmSynthetic for supporting Java APIs without using kotlin dependency.
    • Added support for clickable HTML links by exposing themovementMethod attribute of TextView in builders (#97)
    • Added internal modifiers to some public APIs.
    Source code(tar.gz)
    Source code(zip)
    balloon-1.2.3.aar(150.37 KB)
  • 1.2.2(Sep 2, 2020)

    πŸŽ‰ Released a new version 1.2.2! πŸŽ‰

    What's New?

    • Fixed - Setting larger arrow size causes text to be clipped (#89)
    • Support vector drawable for customized arrow drawable.
    • Removed setSpace function and added the below methods. If the location of the balloon according to the anchor is located at the boundaries on the screen, the balloon will be stick to the end of the screen. In that case, we can resolve by giving margins to the balloon.
    .setMargin(12) // sets the margin on the balloon all directions.
    .setMarginLeft(14) // sets the left margin on the balloon.
    .setMarginRight(14) // sets the right margin on the balloon.
    .setMarginTop(14)
    .setMarginBottom(14)
    
    • Added measureTextWidth function for measuring the exact text size in the custom layout. measures the width of a TextView and set the measured with. If the width of the parent XML layout is wrapped content, and also the widths of TextViews in the parent layout is wrapped content, this functionality will measure the width exactly. We can use this method below way.
    val myTextView = customProfileBalloon.getContentView().findViewById<TextView>(R.id.myTextView)
    customProfileBalloon.measureTextWidth(myTextView)
    
    • Changed internal values to constant definitions.
    • Updated kotlin version to 1.4.0 stable and used single method abstract conversions internally.
    • Updated to compile SDK version to 30 internally.
    Source code(tar.gz)
    Source code(zip)
    balloon-1.2.2.aar(149.72 KB)
Owner
Jaewoong Eum
Android software engineer. Digital Nomad. Open Source Contributor. ❀️ Love coffee, music, magic tricks and writing poems. Coffee Driven Development.
Jaewoong Eum
A Tinder-like Android library to create the swipe cards effect. You can swipe left or right to like or dislike the content.

Swipecards Travis master: A Tinder-like cards effect as of August 2014. You can swipe left or right to like or dislike the content. The library create

Dionysis Lorentzos 2.3k Dec 9, 2022
Created a Tinder like Card Deck & Captain Train like Toolbar

TinderView Created A Simple and Beautiful Tinder like card deck & Captain Train like toolbar. This is heavily based on AndroidSwipeableCardStack, wenc

Aradh Pillai 328 Jun 18, 2022
Android View for displaying and selecting values in a circle-shaped View, with animations and touch gestures.

CircleDisplay Android View for displaying and selecting (by touch) values / percentages in a circle-shaped View, with animations. Features Core featur

Philipp Jahoda 287 Nov 18, 2022
A nicer-looking, more intuitive and highly customizable alternative for radio buttons and dropdowns for Android.

SwipeSelector Undergoing for some API changes for a 2.0 major version, see example usage in the sample module! What and why? Bored of dull looking rad

Iiro Krankka 1.1k Dec 30, 2022
The CustomCalendarView provides an easy and customizable calendar to create a Calendar. It dispaly the days of a month in a grid layout and allows to navigate between months

Custom-Calendar-View To use the CustomCalendarView in your application, you first need to add the library to your application. You can do this by eith

Nilanchala Panigrahy 113 Nov 29, 2022
Material Design implementation for Android 4.0+. Shadows, ripples, vectors, fonts, animations, widgets, rounded corners and more.

Carbon Material Design implementation for Android 4.0 and newer. This is not the exact copy of the Lollipop's API and features. It's a custom implemen

null 3k Dec 30, 2022
A material Switch with icon animations and color transitions

Material Animated Switch A material Switch with icon animations and color transitions Sample video: Youtube Material Animated Switch video Sample app:

AdriΓ‘n Lomas 1.2k Dec 29, 2022
Dali is an image blur library for Android. It contains several modules for static blurring, live blurring and animations.

Dali Dali is an image blur library for Android. It is easy to use, fast and extensible. Dali contains several modules for either static blurring, live

Patrick Favre-Bulle 1k Dec 1, 2022
Simple and lightweight UI library for user new experience, combining floating bottom navigation and bottom sheet behaviour. Simple and beautiful.

Simple and lightweight UI library for user new experience, combining floating bottom navigation and bottom sheet behaviour. Simple and beautiful.

Rizki Maulana 118 Dec 14, 2022
⚑️A highly customizable, powerful and easy-to-use alerting library for Android.

Flashbar A highly customizable, powerful and easy-to-use alerting library for Android. Specs This library allows you to show messages or alerts in you

Aritra Roy 1.7k Dec 7, 2022
A simple, customizable and easy to use swipeable view stack for Android.

SwipeStack A simple, customizable and easy to use swipeable view stack for Android. QuickStart Include the Gradle dependency dependencies { compil

Frederik Schweiger 1.5k Dec 30, 2022
A simple and customizable two or three states Switch View

RMSwitch A simple View that works like a switch, but with more customizations. With the option to choose between two or three states. (from v1.1.0) **

Riccardo Moro 656 Dec 2, 2022
A customizable debug screen to view and edit flags that can be used for development in Jetpack Compose applications

Tweaks A customizable debug screen to view and edit flags that can be used for development in Jetpack Compose applications To include the library add

Guillermo Merino JimΓ©nez 4 Jan 14, 2022
TourGuide is an Android library that aims to provide an easy way to add pointers with animations over a desired Android View

TourGuide TourGuide is an Android library. It lets you add pointer, overlay and tooltip easily, guiding users on how to use your app. Refer to the exa

Tan Jun Rong 2.6k Jan 5, 2023
A beautiful Android custom View that works similar to a range or seekbar. With animations.

ValueBar A beautiful Android custom View that works similar to a range or seekbar. Selection by gesture. With animations. Supporting API level 11+. De

Philipp Jahoda 147 Nov 20, 2022
Highly customizable SlidingLayer as you have seen in Wunderlist

6Wunderkinder SlidingLayer for Android This repository hosts a library that provides an easy way to include an autonomous layer/view that slides from

Microsoft Archive 942 Nov 28, 2022
Customizable Item Setting View Android

ItemSettingView Simple ItemSettingView and Custom Installation Add it in your root build.gradle at the end of repositories: allprojects { reposito

Andhika Yuana 15 Aug 19, 2022
Highly customizable SlidingLayer as you have seen in Wunderlist

6Wunderkinder SlidingLayer for Android This repository hosts a library that provides an easy way to include an autonomous layer/view that slides from

Microsoft Archive 942 Nov 28, 2022
Celebrate more with this lightweight confetti particle system 🎊

Konfetti ?? ?? Celebrate more with this lightweight confetti particle system. Create realistic confetti by implementing this easy to use library. Demo

Dion Segijn 2.7k Jan 2, 2023