Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ballon with custom layout: removeView exception #281

Closed
m1ga opened this issue Nov 26, 2021 · 7 comments
Closed

Ballon with custom layout: removeView exception #281

m1ga opened this issue Nov 26, 2021 · 7 comments

Comments

@m1ga
Copy link

m1ga commented Nov 26, 2021

Please complete the following information:

  • Library Version: 1.4.0
  • Affected Device(s): Pixel 4, Android 12

Describe the Bug:

When running the following code with a custom Layout:

balloon = new Balloon.Builder(TiApplication.getAppCurrentActivity())
                .setArrowSize(arrowSize)
                .setLayout(customView)
                .setArrowOrientation(orientation)
                .setArrowPositionRules(ArrowPositionRules.ALIGN_BALLOON)
                .setArrowPosition(0.5f)
                .setWidth(BalloonSizeSpec.WRAP)
                .setHeight(BalloonSizeSpec.WRAP)
                .setCornerRadius(4f)
                .setAlpha(0.9f)
                .setArrowColor(arrowColor)
                .setBalloonAnimation(BalloonAnimation.ELASTIC)
                .setLifecycleOwner(lifecycle)
                .build();

I receive this error when calling it the second time:

[ERROR] TiExceptionHandler:     android.view.ViewGroup.addViewInner(ViewGroup.java:5247)
[ERROR] TiExceptionHandler:     android.view.ViewGroup.addView(ViewGroup.java:5076)
[ERROR] TiExceptionHandler:     android.view.ViewGroup.addView(ViewGroup.java:5016)
[ERROR] TiExceptionHandler:     android.view.ViewGroup.addView(ViewGroup.java:4988)
[ERROR] TiExceptionHandler:     com.skydoves.balloon.Balloon.initializeCustomLayout(Balloon.kt:594)
[ERROR] TiExceptionHandler:     com.skydoves.balloon.Balloon.initializeBalloonLayout(Balloon.kt:576)
[ERROR] TiExceptionHandler:     com.skydoves.balloon.Balloon.createByBuilder(Balloon.kt:194)
[ERROR] TiExceptionHandler:     com.skydoves.balloon.Balloon.<init>(Balloon.kt:187)
[ERROR] TiExceptionHandler:     com.skydoves.balloon.Balloon.<init>(Balloon.kt:131)
[ERROR] TiExceptionHandler:     com.skydoves.balloon.Balloon$Builder.build(Balloon.kt:2533)
[ERROR] V8Exception: Exception occurred at /alloy/controllers/index.js:191: Uncaught Error: The specified child already has a parent. You must call removeView() on the child's parent first.

There was am older issue #149 that already fixed some places. This might be another one.

Expected Behavior:

No expception, being able to create another ballon with me options.

@skydoves
Copy link
Owner

skydoves commented Dec 2, 2021

Hey @m1ga,
This issue seems also related to #280. Could you try to build with the 1.4.1-SNAPSHOT?

@m1ga
Copy link
Author

m1ga commented Dec 2, 2021

Hi @skydoves. Thanks for the feedback. I've tested the snapshot version and still see the error:

android.view.ViewGroup.addViewInner(ViewGroup.java:5235)
android.view.ViewGroup.addView(ViewGroup.java:5064)
android.view.ViewGroup.addView(ViewGroup.java:5004)
android.view.ViewGroup.addView(ViewGroup.java:4976)
com.skydoves.balloon.Balloon.initializeCustomLayout(Balloon.kt:596)
com.skydoves.balloon.Balloon.initializeBalloonLayout(Balloon.kt:578)
com.skydoves.balloon.Balloon.createByBuilder(Balloon.kt:196)
com.skydoves.balloon.Balloon.<init>(Balloon.kt:189)
com.skydoves.balloon.Balloon.<init>(Balloon.kt:133)
com.skydoves.balloon.Balloon$Builder.build(Balloon.kt:2590)

It is just two lines below the old error

@skydoves
Copy link
Owner

skydoves commented Dec 4, 2021

@m1ga,
Can I get more context of your customlayout?
If the customlayout has a parent, you can get the issue. And just I was wondering if you could use the XML layout file instead of the inflated layout on the setLayout method. Thanks!

@m1ga
Copy link
Author

m1ga commented Dec 4, 2021

It's a bit more complicated 😄 I'm creating a module for Appcelerator Titanium so you can create your views in XML/JS and show it with the help of your module
https://github.com/m1ga/ti.popover/tree/main/android/src/ti/popover
Relevant files are PopoverProxy (connection between JS and Java) and PopoverView (create native Views).

Inside PopoverView I'm receiving the Titanium View (TiUIVIew) as a parameter and get it's native View.

Then after that the Balloon part is here.

So I have to make sure somehow that my layout doesn't have any more parents? In fact I had a version running once where it opened every click but I ended up in getting a new balloon arrow add to my view every time.

Later on in Titanium you wrap the content of the popup like this

<Popover module="ti.popover" id="popover">
    <View id="contentView">
        <ImageView id="img"/>
        <Label text="test" id="lbl"/>
    </View>
</Popover>

and can run

$.popover.show({
	view: cv,
	direction: direction
})

but don't want to bother you with framework insides 😄

@skydoves
Copy link
Owner

skydoves commented Dec 4, 2021

Thanks for your very details. 😄
Yes, exactly we should check if the custom view has a parent because the balloon lays down the custom view on the internal body layout.

If you don't have to maintain the original view hierarchies of the root view, you can achieve it like the example below:

ViewGroup parentView = customView.getParent();
if (parentView != null) {
  parentView.removeView(customView);
}
balloonBuilder.setLayout(customView);

@m1ga
Copy link
Author

m1ga commented Dec 4, 2021

Ok, that is an embarrassing easy fix 🤣
Works fine now. Thank you so much for your help 👍

@skydoves
Copy link
Owner

skydoves commented Dec 4, 2021

That's great to hear that. 😄
Thanks, @m1ga for digging this issue. It'll be handled internally on the next release. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants