: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
  • setArrowOrientationRules(ArrowOrientationRules.ALIGN_ANCHOR) does not work on a custom layout.

    setArrowOrientationRules(ArrowOrientationRules.ALIGN_ANCHOR) does not work on a custom layout.

    Please complete the following information:

    • Library Version 1.4.8
    • Affected Device(s) Huawei P20

    Describe the Bug:

    Maybe I'm wrong, but I understand that when I set ArrowOrientationRules.ALIGN_ANCHOR, the arrow should automatically turn towards the "anchor", is that right? At the same time, setArrowOrientation should either be omitted or ignored. But, in this case, I always have an arrow at the bottom, although, the anchor object is located on the right.

    opened by MKadykov 2
  • 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.0)
  • 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)
  • 1.2.1(Aug 7, 2020)

    ๐ŸŽ‰ Released a new version 1.2.1! ๐ŸŽ‰

    What's New?

    • Added update(anchor: View), update(anchor: View, xOff: Int, yOff: Int) functionalities. Updating popup and arrow position of the popup based on a new target anchor view with additional x-off and y-off. (#68)
    • Updated appcompat version to 1.2.0 stable.
    • Changed android.arch.lifecycle package to androidx.arch.lifecycle internally.
    • Fixed not working properly when setDismissWhenTouchOutside with BalloonAnimation.CIRCULAR. (#85)
    Source code(tar.gz)
    Source code(zip)
    balloon-1.2.1.aar(148.76 KB)
  • 1.2.0(Jul 30, 2020)

    ๐ŸŽ‰ Released a new version 1.2.0! ๐ŸŽ‰

    What's New?

    • Arrow not placing the first time at the right position (#74)
    • Added a setDismissWhenLifecycleOnPause functionality. (#77) The balloon popup will be dismissed when the lifecycle owner is on pause status. This method must be work used with 1setLifecycleOwner.
    • Added setIconGravity(value: IconGravity) functionality for deciding gravity of the icon.
    • Added OnBalloonInitializedListener for listening initialized balloon content. (when balloon popup is shown)
    Source code(tar.gz)
    Source code(zip)
    balloon-1.2.0.aar(148.18 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
Arrow-Maven-Template - A template project for Arrow with Maven. It defines an application and a couple small examples

Arrow-Maven-Template A template project for Arrow on Maven. See the official doc

ฮ›RROW 0 Jan 11, 2022
Functional Kotlin & Arrow based library for generating and verifying JWTs and JWSs

kJWT Functional Kotlin & Arrow based library for generating and verifying JWTs and JWSs. JWS JWT The following Algorithms are supported: HS256 HS384 H

Peter vR 31 Dec 25, 2022
๐Ÿš† Retrofit adapters for modeling network responses with Kotlin Result, Jetpack Paging3, and Arrow Either.

Retrofit Adapters ?? Retrofit adapters for modeling network responses with Kotlin Result, Jetpack Paging3, and Arrow Either. Sandwich If you're intere

Jaewoong Eum 293 Dec 26, 2022
Arrow Endpoint offers a composable Endpoint datatype, that allows us easily define an Endpoint from which we can derive clients, servers & documentation.

Arrow Endpoint Arrow Endpoint offers a composable Endpoint datatype, that allows us easily define an Endpoint from which we can derive clients, server

ฮ›RROW 23 Dec 15, 2022
Arrow Endpoint offers a composable Endpoint datatype, that allows us easily define an Endpoint from which we can derive clients, servers & documentation.

Arrow Endpoint Arrow Endpoint offers a composable Endpoint datatype, that allows us easily define an Endpoint from which we can derive clients, server

ฮ›RROW 8 Oct 11, 2021
Exercises for Functional Programming learning in Kotlin with Arrow

Exercises for Functional Programming in Kotlin with Arrow-kt Exercises and practice code for Functional Programming learning in Kotlin with Arrow Requ

Jack Lo 3 Nov 11, 2021
:closed_umbrella: An easy way to implement modern permission instructions popup.

Needs An easy way to implement modern permission instructions popup. Needs can be fully customized and showing with animations. Download Gradle Add be

Jaewoong Eum 609 Dec 8, 2022
Open source Crypto Currency Tracker Android App made fully in Kotlin

CoinBit CoinBit is a beautiful CryptoCurrency app, completely open sourced and 100% in kotlin. It supports following features Track prices of over 300

Pranay Airan 50 Dec 5, 2022
A simple xposed module that helps you fully control your location.

FuckLocation An simple xposed module that helps you fully control your location. ไธ€ไธชๅฏไปฅๅธฎๅŠฉไฝ ๅฎŒๅ…จๆŽงๅˆถไฝ็ฝฎๆŽˆๆƒ็š„ๆจกๅ— Currently, you may return custom location to speci

null 218 Dec 30, 2022
YouTube Player library for Android and Chromecast, stable and customizable.

android-youtube-player android-youtube-player is a stable and customizable open source YouTube player for Android. It provides a simple View that can

Pierfrancesco Soffritti 2.9k Jan 2, 2023
:octocat: A demo project based on MVVM architecture and material design & animations.

GithubFollows A simple demo project based on MVVM clean architecture and material design & animations. Architecture Specs & Open-source libraries Mini

Jaewoong Eum 289 Jan 4, 2023
๐ŸŽฌ A demo project for The Movie DB based on Kotlin MVVM architecture and material design & animations.

TheMovies A simple project for The Movie DB based on Kotlin MVVM clean architecture and material design & animations. How to build on your environment

Jaewoong Eum 419 Jan 7, 2023
Educational App made with Retrofit, Coroutines, Navigation Component, Room, Dagger Hilt, Flow & Material Motion Animations.

TechHub TechHub is a sample educational app that provides courses for people who want to learn new skills in mostly tech-related areas. The goal of th

Jon Areas 32 Dec 20, 2022
A highly customizable calendar library for Android, powered by RecyclerView.

CalendarView A highly customizable calendar library for Android, powered by RecyclerView. With this library, your calendar will look however you want

Kizito Nwose 3.4k Jan 3, 2023
An Easy-to-use Kotlin based Customizable Modules Collection with Material Layouts by BlackBeared.

Fusion By BlackBeared An Easy-to-use Kotlin based Customizable Library with Material Layouts by @blackbeared. Features Custom Floating Action Buttons

Sandip Savaliya 38 Oct 5, 2022
Lightweight data loading and caching library for android

ColdStorage A lightweight data loading and caching library for android Quicklinks Feature requests: Got a new requirement? Request it here and it will

Cryptic Minds 41 Oct 17, 2022
StaticLog - super lightweight static logging for Kotlin, Java and Android

StaticLog StaticLog is a super lightweight logging library implemented in pure Kotlin (https://kotlinlang.org). It is designed to be used in Kotlin, J

Julian Pfeifer 28 Oct 3, 2022
๐ŸšŸ Lightweight, and simple scheduling library made for Kotlin (JVM)

Haru ?? Lightweight, and simple scheduling library made for Kotlin (JVM) Why did you build this? I built this library as a personal usage library to h

Noel 13 Dec 16, 2022
A lightweight and simple Kotlin library for deep link handling on Android ๐Ÿ”—.

A lightweight and simple Kotlin library for deep link handling on Android ??.

Jeziel Lago 101 Aug 14, 2022