Skip to content

Commit

Permalink
Merge pull request #613 from jimmithy/main
Browse files Browse the repository at this point in the history
Support detached Fragments by removing references to the Activity
  • Loading branch information
skydoves authored Aug 22, 2024
2 parents 29e5d9a + 515932f commit ae18002
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 36 deletions.
30 changes: 17 additions & 13 deletions balloon/src/main/kotlin/com/skydoves/balloon/Balloon.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package com.skydoves.balloon

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Bitmap
Expand Down Expand Up @@ -97,7 +98,6 @@ import com.skydoves.balloon.extensions.getSumOfIntrinsicWidth
import com.skydoves.balloon.extensions.getViewPointOnScreen
import com.skydoves.balloon.extensions.isAPILevelHigherThan23
import com.skydoves.balloon.extensions.isExistHorizontalDrawable
import com.skydoves.balloon.extensions.isFinishing
import com.skydoves.balloon.extensions.px2Sp
import com.skydoves.balloon.extensions.runOnAfterSDK22
import com.skydoves.balloon.extensions.runOnAfterSDK23
Expand Down Expand Up @@ -904,18 +904,22 @@ public class Balloon private constructor(
}

private fun canShowBalloonWindow(anchor: View): Boolean {
return !isShowing &&
// If the balloon is already destroyed depending on the lifecycle,
// We should not allow showing the popupWindow, it's related to `relay()` method. (#46)
!destroyed &&
// We should check the current Activity is running.
// If the Activity is finishing, we can't attach the popupWindow to the Activity's window. (#92)
!context.isFinishing &&
// We should check the contentView is already attached to the decorView or backgroundView in the popupWindow.
// Sometimes there is a concurrency issue between show and dismiss the popupWindow. (#149)
bodyWindow.contentView.parent == null &&
// we should check the anchor view is attached to the parent's window.
ViewCompat.isAttachedToWindow(anchor)
// If the balloon is already showing, we don't to try and show it again.
if (isShowing) return false

// If the balloon is already destroyed depending on the lifecycle,
// We should not allow showing the popupWindow, it's related to `relay()` method. (#46)
if (destroyed) return false

// If the Activity is finishing, we can't attach the popupWindow to the Activity's window. (#92)
if ((context as? Activity)?.isFinishing == true) return false

// We should check the contentView is already attached to the decorView or backgroundView in the popupWindow.
// Sometimes there is a concurrency issue between show and dismiss the popupWindow. (#149)
if (bodyWindow.contentView.parent != null) return false

// we should check the anchor view is attached to the parent's window.
return ViewCompat.isAttachedToWindow(anchor)
}

private fun showOverlayWindow(anchor: View, subAnchors: List<View>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,8 @@

package com.skydoves.balloon.extensions

import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.graphics.drawable.Drawable
import androidx.activity.ComponentActivity
import androidx.annotation.DimenRes
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
Expand Down Expand Up @@ -54,21 +51,4 @@ internal fun Context.contextColor(resource: Int): Int {
@JvmSynthetic
internal fun Context.contextDrawable(resource: Int): Drawable? {
return AppCompatResources.getDrawable(this, resource)
}

/** returns if an Activity is finishing or not. */
internal val Context.isFinishing: Boolean
@JvmSynthetic inline get() = this is Activity && this.isFinishing

/** returns an activity from a context. */
@JvmSynthetic
internal fun Context.getActivity(): ComponentActivity? {
var context = this
while (context is ContextWrapper) {
if (context is ComponentActivity) {
return context
}
context = context.baseContext
}
return null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ internal class FragmentBalloonLazy<out T : Balloon.Factory>(
} else {
fragment
}
val instance = factory.create(fragment.requireActivity(), lifecycle)
val instance = factory.create(fragment.requireContext(), lifecycle)
cached = instance

return instance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ internal class ViewBalloonLazy<out T : Balloon.Factory>(
} else {
fragment
}
instance = factory.create(fragment.requireActivity(), lifecycle)
instance = factory.create(fragment.requireContext(), lifecycle)
cached = instance
} else {
throw IllegalArgumentException(
Expand Down

0 comments on commit ae18002

Please sign in to comment.