diff --git a/.github/ISSUE_TEMPLATE/n1_report_issue.yml b/.github/ISSUE_TEMPLATE/n1_report_issue.yml
new file mode 100644
index 0000000..fdb44fe
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/n1_report_issue.yml
@@ -0,0 +1,97 @@
+name: 🐞 Issue report
+description: Report an issue in Floating-Bubble-View
+labels: [Bug]
+body:
+
+ - type: textarea
+ id: reproduce-steps
+ attributes:
+ label: Steps to reproduce
+ description: Provide an example of the issue.
+ placeholder: |
+ Example:
+ 1. First step
+ 2. Second step
+ 3. Issue here
+ validations:
+ required: true
+
+ - type: textarea
+ id: expected-behavior
+ attributes:
+ label: Expected behavior
+ description: Explain what you should expect to happen.
+ placeholder: |
+ Example:
+ "This should happen..."
+ validations:
+ required: true
+
+ - type: textarea
+ id: actual-behavior
+ attributes:
+ label: Actual behavior
+ description: Explain what actually happens.
+ placeholder: |
+ Example:
+ "This happened instead..."
+ validations:
+ required: true
+
+ - type: textarea
+ id: crash-logs
+ attributes:
+ label: Crash logs
+ placeholder: |
+ You can paste the crash logs in plain text or upload it as an attachment.
+
+ - type: input
+ id: floating-bubble-view-version
+ attributes:
+ label: Floating-Bubble-View version
+ placeholder: |
+ Example: "0.0.3"
+ validations:
+ required: true
+
+ - type: input
+ id: android-version
+ attributes:
+ label: Android version
+ description: You can find this somewhere in your Android settings.
+ placeholder: |
+ Example: "Android 13"
+ validations:
+ required: true
+
+ - type: input
+ id: device
+ attributes:
+ label: Device
+ description: List your device and model.
+ placeholder: |
+ Example: "Google Pixel 6 pro"
+ validations:
+ required: true
+
+ - type: textarea
+ id: other-details
+ attributes:
+ label: Other details
+ placeholder: |
+ Additional details and attachments.
+
+ - type: checkboxes
+ id: acknowledgements
+ attributes:
+ label: Acknowledgements
+ description: Read this carefully, we will close and ignore your issue if you skimmed through this.
+ options:
+ - label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open or closed issue.
+ required: true
+ - label: I have written a short but informative title.
+ required: true
+ - label: I have updated the library to the latest **[Version](https://github.com/torrydo/Floating-Bubble-View/releases/latest)**.
+ required: true
+ - label: I will fill out all of the requested information in this form.
+ required: true
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/n2_request_feature.yml b/.github/ISSUE_TEMPLATE/n2_request_feature.yml
new file mode 100644
index 0000000..316793a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/n2_request_feature.yml
@@ -0,0 +1,37 @@
+name: ⭐ Feature request
+description: Suggest a feature to improve Floating-Bubble-View
+labels: [Feature request]
+body:
+
+ - type: textarea
+ id: feature-description
+ attributes:
+ label: Describe your suggested feature
+ description: How can Floating-Bubble-View be improved?
+ placeholder: |
+ Example:
+ "It should work like this..."
+ validations:
+ required: true
+
+ - type: textarea
+ id: other-details
+ attributes:
+ label: Other details
+ placeholder: |
+ Additional details and attachments.
+
+ - type: checkboxes
+ id: acknowledgements
+ attributes:
+ label: Acknowledgements
+ description: Read this carefully, we will close and ignore your issue if you skimmed through this.
+ options:
+ - label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open or closed issue.
+ required: true
+ - label: I have written a short but informative title.
+ required: true
+ - label: I have updated the library to the latest **[Version](https://github.com/torrydo/Floating-Bubble-View/releases/latest)**.
+ required: true
+ - label: I will fill out all of the requested information in this form.
+ required: true
\ No newline at end of file
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index ebf469d..d76dae0 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -7,11 +7,11 @@
-
+
-
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 4bb04e5..1eef794 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -7,6 +7,7 @@
+
diff --git a/FloatingBubbleView/build.gradle b/FloatingBubbleView/build.gradle
index 3d03d9a..90c923b 100644
--- a/FloatingBubbleView/build.gradle
+++ b/FloatingBubbleView/build.gradle
@@ -37,7 +37,7 @@ android {
compose true
}
- composeOptions{
+ composeOptions {
kotlinCompilerExtensionVersion "1.3.2"
}
@@ -45,15 +45,13 @@ android {
dependencies {
-
implementation("androidx.core:core-ktx:1.6.0")
implementation("androidx.appcompat:appcompat:1.4.0")
implementation("androidx.dynamicanimation:dynamicanimation:1.0.0")
- def compose_version = "1.3.1"
- implementation "androidx.compose.foundation:foundation:${compose_version}"
+ implementation "androidx.compose.foundation:foundation:1.3.1"
- implementation "io.github.torrydo:screen-easy:0.0.2"
+ implementation "io.github.torrydo:screen-easy:0.1.0"
}
\ No newline at end of file
diff --git a/FloatingBubbleView/src/main/AndroidManifest.xml b/FloatingBubbleView/src/main/AndroidManifest.xml
index 866eca2..2b58885 100644
--- a/FloatingBubbleView/src/main/AndroidManifest.xml
+++ b/FloatingBubbleView/src/main/AndroidManifest.xml
@@ -2,6 +2,7 @@
+
diff --git a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/AndroidVersions.kt b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/AndroidVersions.kt
index 28fe608..383e022 100644
--- a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/AndroidVersions.kt
+++ b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/AndroidVersions.kt
@@ -4,7 +4,7 @@ import android.os.Build
internal object AndroidVersions {
-// const val `13` = Build.VERSION_CODES.TIRAMISU // 33
+ const val `13` = Build.VERSION_CODES.TIRAMISU // 33
const val `12` = Build.VERSION_CODES.S // 31
const val `11` = Build.VERSION_CODES.R // 30
const val `10` = Build.VERSION_CODES.Q // 29
diff --git a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/BaseFloatingViewBinding.kt b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/BaseFloatingViewBinding.kt
index bd94f8d..2c0bcc7 100644
--- a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/BaseFloatingViewBinding.kt
+++ b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/BaseFloatingViewBinding.kt
@@ -23,10 +23,10 @@ internal open class BaseFloatingViewBinding(
* */
open fun show() {
try {
- if(binding.root.windowToken != null) return
+// if(binding.root.windowToken != null) return
super.show(binding.root)
}catch (e: Exception){
-// Log.d("<>", "show: ${e.stackTraceToString()}"); this line show error in some cases
+// Log.e("<>FBV", "show: ${e.stackTraceToString()}"); //this line show error in some cases
}
}
diff --git a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/ComposeLifecycleOwner.kt b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/ComposeLifecycleOwner.kt
index ae35cbd..2dcb999 100644
--- a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/ComposeLifecycleOwner.kt
+++ b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/ComposeLifecycleOwner.kt
@@ -53,13 +53,10 @@ internal class ComposeLifecycleOwner : LifecycleOwner, SavedStateRegistryOwner {
}
- // LifecycleOwner methods
private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
override fun getLifecycle(): Lifecycle = lifecycleRegistry
-
- // SavedStateRegistry methods
private val savedStateRegistryController = SavedStateRegistryController.create(this)
override val savedStateRegistry: SavedStateRegistry
get() = savedStateRegistryController.savedStateRegistry
diff --git a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/ExpandableView.kt b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/ExpandableView.kt
index 5b428f8..03a9bc8 100644
--- a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/ExpandableView.kt
+++ b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/ExpandableView.kt
@@ -1,11 +1,11 @@
package com.torrydo.floatingbubbleview
import android.content.Context
-import android.view.Gravity
import android.view.View
import android.view.WindowManager
import androidx.annotation.StyleRes
import androidx.compose.runtime.Composable
+import com.torrydo.screenez.ScreenRotation
class ExpandableView(
private val builder: Builder,
@@ -58,7 +58,7 @@ class ExpandableView(
fun remove() {
- if(builder.view != null){
+ if (builder.view != null) {
super.remove(builder.view!!)
builder.listener.onCloseExpandableView()
return
@@ -91,12 +91,37 @@ class ExpandableView(
override fun setupLayoutParams() {
super.setupLayoutParams()
+ var mFlag = WindowManager.LayoutParams.FLAG_DIM_BEHIND
+ var mHeight = WindowManager.LayoutParams.WRAP_CONTENT
+ var mWidth = WindowManager.LayoutParams.MATCH_PARENT
+ var mX: Int? = null
+
+ if (builder.isDrawUnderSystemUI) {
+ mFlag = WindowManager.LayoutParams.FLAG_DIM_BEHIND or
+ WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
+ WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
+
+ mWidth = sez.fullWidth
+ mHeight = sez.fullHeight
+
+ if (sez.screenRotation == ScreenRotation.LANDSCAPE) {
+ mX = -sez.navBarHeight
+ }
+
+ }
+
windowParams.apply {
- width = WindowManager.LayoutParams.MATCH_PARENT
- gravity = Gravity.TOP
- flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND
+ width = mWidth
+ height = mHeight
+ flags = mFlag
dimAmount = builder.dim // default = 0.5f
+// this.verticalMargin = 0.07f // so fun hihi
+// y = 100 // so fun hihihi
+ if (mX != null) {
+ x = mX
+ }
+
builder.viewStyle?.let {
windowAnimations = it
}
@@ -117,8 +142,18 @@ class ExpandableView(
internal var listener = object : Listener {}
+ internal var isDrawUnderSystemUI: Boolean = false
+
internal var dim = 0.5f
+ /**
+ * Allow the expandable-view to display under the system UI elements
+ * */
+ internal fun drawUnderSystemUI(included: Boolean): Builder {
+ isDrawUnderSystemUI = included
+ return this
+ }
+
fun view(view: View): Builder {
if (composeView != null) {
throw IllegalStateException("Cannot pass view after setting composable")
diff --git a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBottomBackground.kt b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBottomBackground.kt
index 09a8b71..cdb89fa 100644
--- a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBottomBackground.kt
+++ b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBottomBackground.kt
@@ -4,7 +4,6 @@ import android.view.Gravity
import android.view.LayoutInflater
import android.view.WindowManager
import com.torrydo.floatingbubbleview.databinding.BottomBackgroundBinding
-import com.torrydo.screenez.ScreenEz
internal class FloatingBottomBackground(
private val builder: FloatingBubble.Builder
@@ -44,7 +43,7 @@ internal class FloatingBottomBackground(
windowParams.apply {
width = WindowManager.LayoutParams.MATCH_PARENT
- height = ScreenEz.fullHeight / 5
+ height = sez.fullHeight / 5
gravity = Gravity.BOTTOM or Gravity.CENTER
flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH or
diff --git a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBubble.kt b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBubble.kt
index d3f5471..2363f3c 100644
--- a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBubble.kt
+++ b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBubble.kt
@@ -40,7 +40,6 @@ internal constructor(
// listener ------------------------------------------------------------------------------------
-
interface Action {
/**
@@ -77,8 +76,8 @@ internal constructor(
internal fun showIcon() {
- if(builder.composeLifecycleOwner != null){
- if(isComposeInit.not()){
+ if (builder.composeLifecycleOwner != null) {
+ if (isComposeInit.not()) {
builder.composeLifecycleOwner?.onCreate()
isComposeInit = true
}
@@ -94,7 +93,7 @@ internal constructor(
internal fun removeIcon() {
- if(builder.composeLifecycleOwner != null && isComposeInit){
+ if (builder.composeLifecycleOwner != null && isComposeInit) {
builder.composeLifecycleOwner!!.apply {
onPause()
onStop()
@@ -126,8 +125,6 @@ internal constructor(
override fun onMove(x: Float, y: Float) {
- val bubbleSizeCompat = Size(builder.bubbleView!!.width, builder.bubbleView!!.height)
-
when (builder.behavior) {
BubbleBehavior.DYNAMIC_CLOSE_BUBBLE -> {
bubbleView.updateLocationUI(x, y)
@@ -139,11 +136,14 @@ internal constructor(
if (isFingerInsideClosableArea(x, y)) {
if (isBubbleAnimated.not()) {
- val xOffset = (closeBubbleView!!.width - bubbleSizeCompat.width) / 2
- val yOffset = (closeBubbleView!!.height - bubbleSizeCompat.height) / 2
+ val bWidth = builder.bubbleView!!.width
+ val bHeight = builder.bubbleView!!.height
- val xUpdated = closeBubbleView!!.baseX.toFloat() + xOffset
- val yUpdated = closeBubbleView!!.baseY.toFloat() + yOffset
+ val xOffset = (closeBubbleView!!.width - bWidth) / 2
+ val yOffset = (closeBubbleView!!.height - bHeight) / 2
+
+ val xUpdated = (closeBubbleView!!.baseX + xOffset).toFloat()
+ val yUpdated = (closeBubbleView!!.baseY + yOffset).toFloat()
bubbleView.animateTo(xUpdated, yUpdated)
bubbleView.setLocation(xUpdated, yUpdated)
@@ -197,9 +197,12 @@ internal constructor(
}
private fun isFingerInsideClosableArea(x: Float, y: Float): Boolean {
+ // because x and y of the finger which we got from MotionEvent included the cutout and the nav-bar, so we must exclude them
+ val mX = x - sez.safePaddingLeft
+ val mY = y - sez.safePaddingTop
return closeBubbleView?.distanceRatioFromLocationToClosableArea(
- x = x,
- y = y
+ x = mX,
+ y = mY
) == 0.0f
}
@@ -227,7 +230,10 @@ internal constructor(
internal var isAnimateToEdgeEnabled = true
internal var isBottomBackgroundEnabled = false
- internal var distanceToCloseDp = 100
+ internal var distanceToClosePx = 200
+
+ internal var closeBubbleBottomPaddingPx = 80
+ private set
internal var listener: Listener? = null
internal var serviceInteractor: ServiceInteractor? = null
@@ -235,7 +241,7 @@ internal constructor(
internal var behavior: BubbleBehavior = BubbleBehavior.FIXED_CLOSE_BUBBLE
// composable
- internal var composeView: (@Composable ()->Unit)? = null
+ internal var composeView: (@Composable () -> Unit)? = null
internal var composeLifecycleOwner: ComposeLifecycleOwner? = null
@@ -253,7 +259,7 @@ internal constructor(
* @param dp distance between bubble and close-bubble
* */
fun distanceToClose(dp: Int): Builder {
- this.distanceToCloseDp = dp
+ this.distanceToClosePx = dp.toPx()
return this
}
@@ -282,14 +288,8 @@ internal constructor(
}
fun bubble(content: @Composable () -> Unit): Builder {
-// bubbleView = FloatingComposeView(context).apply {
-// setContent { content() }
-// }
composeLifecycleOwner = ComposeLifecycleOwner()
-// composeLifecycleOwner?.attachToDecorView(bubbleView!!)
-
composeView = content
-
return this
}
diff --git a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBubbleService.kt b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBubbleService.kt
index 8ec7c74..546edc5 100644
--- a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBubbleService.kt
+++ b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBubbleService.kt
@@ -1,5 +1,6 @@
package com.torrydo.floatingbubbleview
+import android.annotation.SuppressLint
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
@@ -15,7 +16,6 @@ import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.PRIORITY_MIN
import androidx.core.app.NotificationManagerCompat
import com.torrydo.floatingbubbleview.exceptions.PermissionDeniedException
-import com.torrydo.screenez.ScreenEz
abstract class FloatingBubbleService : Service() {
@@ -53,12 +53,12 @@ abstract class FloatingBubbleService : Service() {
override fun onCreate() {
super.onCreate()
- ScreenEz.with(this.applicationContext)
-
if (!isDrawOverlaysPermissionGranted()) {
throw PermissionDeniedException()
}
+ sez.with(this.applicationContext)
+
isRunning = true
orientation = this.resources.configuration.orientation
currentRoute = initialRoute()
@@ -76,14 +76,13 @@ abstract class FloatingBubbleService : Service() {
}
override fun onConfigurationChanged(newConfig: Configuration) {
- super.onConfigurationChanged(newConfig)
+
+ sez.refresh()
// Check if the configuration has actually changed.
if (newConfig.orientation != orientation) {
val newOrientation = newConfig.orientation
- ScreenEz.refresh()
-
when (newOrientation) {
Configuration.ORIENTATION_PORTRAIT -> {
if (currentRoute == Route.Bubble) {
@@ -118,6 +117,7 @@ abstract class FloatingBubbleService : Service() {
orientation = newOrientation
}
+ super.onConfigurationChanged(newConfig)
}
override fun onDestroy() {
@@ -218,6 +218,7 @@ abstract class FloatingBubbleService : Service() {
/**
* show the notification or update if already exists
* */
+ @SuppressLint("MissingPermission")
fun notify(notification: Notification) {
if (isNotificationInitialized) {
diff --git a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBubbleView.kt b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBubbleView.kt
index b83c3fc..47c2e54 100644
--- a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBubbleView.kt
+++ b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingBubbleView.kt
@@ -4,11 +4,9 @@ import android.annotation.SuppressLint
import android.content.res.Configuration
import android.graphics.Point
import android.graphics.PointF
-import android.util.Log
import android.view.*
import androidx.compose.ui.platform.ComposeView
import com.torrydo.floatingbubbleview.databinding.BubbleBinding
-import com.torrydo.screenez.ScreenEz
import kotlin.math.abs
internal class FloatingBubbleView(
@@ -25,13 +23,13 @@ internal class FloatingBubbleView(
private val rawPointOnDown = PointF(0f, 0f)
private val newPoint = Point(0, 0)
- private var halfScreenWidth = ScreenEz.fullWidth / 2
+ private var halfScreenWidth = sez.fullWidth / 2
private var orientation = -1
init {
- orientation = if (ScreenEz.fullHeight >= ScreenEz.fullWidth) {
+ orientation = if (sez.fullHeight >= sez.fullWidth) {
Configuration.ORIENTATION_PORTRAIT
} else {
Configuration.ORIENTATION_LANDSCAPE
@@ -64,7 +62,7 @@ internal class FloatingBubbleView(
endX = 0
} else {
startX = iconX
- endX = ScreenEz.safeWidth - bubbleWidthCompat
+ endX = sez.safeWidth - bubbleWidthCompat
}
AnimHelper.startSpringX(
@@ -129,7 +127,7 @@ internal class FloatingBubbleView(
//region prevent bubble Y point move outside the screen
val safeTopY = 0
- val safeBottomY = ScreenEz.safeHeight - binding.root.height
+ val safeBottomY = sez.safeHeight - binding.root.height
val isAboveStatusBar = newPoint.y < safeTopY
val isUnderSoftNavBar = newPoint.y > safeBottomY
@@ -209,11 +207,12 @@ internal class FloatingBubbleView(
}
}
- fun ignoreChildClickEvent(event: MotionEvent): Boolean{
- when(event.action){
+ fun ignoreChildClickEvent(event: MotionEvent): Boolean {
+ when (event.action) {
MotionEvent.ACTION_DOWN -> {
ignoreClick = false
}
+
MotionEvent.ACTION_MOVE -> {
if (abs(event.x) > MAX_X_MOVE || abs(event.y) > MAX_Y_MOVE) {
ignoreClick = true
@@ -229,7 +228,7 @@ internal class FloatingBubbleView(
binding.bubbleRoot.apply {
- afterMeasured { updateGestureExclusion(builder.context) }
+ afterMeasured { updateGestureExclusion() }
doOnTouchEvent = {
handleMovement(it)
diff --git a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingCloseBubbleView.kt b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingCloseBubbleView.kt
index 1f1eb90..7092ac3 100644
--- a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingCloseBubbleView.kt
+++ b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/FloatingCloseBubbleView.kt
@@ -1,10 +1,8 @@
package com.torrydo.floatingbubbleview
-import android.util.Log
import android.view.LayoutInflater
import android.view.WindowManager
import com.torrydo.floatingbubbleview.databinding.CloseBubbleBinding
-import com.torrydo.screenez.ScreenEz
internal class FloatingCloseBubbleView(
private val builder: FloatingBubble.Builder,
@@ -13,51 +11,35 @@ internal class FloatingCloseBubbleView(
initializer = CloseBubbleBinding.inflate(LayoutInflater.from(builder.context)),
) {
- companion object {
- internal const val DEFAULT_PADDING_BOTTOM_PX = 30
- }
-
private var LIMIT_FLY_HEIGHT: Int
var halfWidthPx: Int
var halfHeightPx: Int
- private var halfScreenWidth: Int
+ private var halfSafeScreenWidth: Int
var baseX: Int
var baseY: Int
private var centerCloseBubbleX: Int
private var centerCloseBubbleY: Int
- private var closablePerimeterPx: Int
-
init {
builder.closeBubbleSizePx.also {
width = it.width
height = it.height
}
- LIMIT_FLY_HEIGHT = ScreenEz.fullHeight / 10
+ LIMIT_FLY_HEIGHT = sez.fullHeight / 10
- halfScreenWidth = ScreenEz.safeWidth / 2
+ halfSafeScreenWidth = sez.safeWidth / 2
halfWidthPx = width / 2
halfHeightPx = height / 2
- baseX = halfScreenWidth - halfWidthPx
- baseY = ScreenEz.fullHeight -
- height -
- ScreenEz.navBarHeight -
- ScreenEz.statusBarHeight -
- DEFAULT_PADDING_BOTTOM_PX
-
- if (ScreenEz.isPortrait().not()) {
- baseY = baseY - DEFAULT_PADDING_BOTTOM_PX + ScreenEz.navBarHeight
- }
+ baseX = halfSafeScreenWidth - halfWidthPx
+ baseY = sez.safeHeight - height - builder.closeBubbleBottomPaddingPx
- centerCloseBubbleX = halfScreenWidth
+ centerCloseBubbleX = halfSafeScreenWidth
centerCloseBubbleY = baseY + halfHeightPx
- closablePerimeterPx = builder.distanceToCloseDp.toPx()
-
setupLayoutParams()
setupCloseBubbleProperties()
}
@@ -67,8 +49,9 @@ internal class FloatingCloseBubbleView(
windowParams.apply {
flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
- WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH /*or
- WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION*/
+// WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
+// WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION or
+ WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
}
}
@@ -81,10 +64,11 @@ internal class FloatingCloseBubbleView(
* */
fun distanceRatioFromBubbleToClosableArea(x: Int, y: Int): Float {
- val bubbleSize = builder.bubbleSize()
+ val bWidth = builder.bubbleView!!.width
+ val bHeight = builder.bubbleView!!.height
- val centerBubbleX = x + bubbleSize.width / 2
- val centerBubbleY = y + bubbleSize.height / 2
+ val centerBubbleX = x + bWidth / 2
+ val centerBubbleY = y + bHeight / 2
val distanceToBubble = XMath.distance(
x1 = centerCloseBubbleX.toDouble(),
@@ -92,7 +76,7 @@ internal class FloatingCloseBubbleView(
x2 = centerBubbleX.toDouble(),
y2 = centerBubbleY.toDouble()
)
- val distanceRatio = (closablePerimeterPx.toDouble() / distanceToBubble).let {
+ val distanceRatio = (builder.distanceToClosePx.toDouble() / distanceToBubble).let {
if (it > 1) return@let 0
return@let 1 - it
}.toFloat()
@@ -100,14 +84,18 @@ internal class FloatingCloseBubbleView(
return distanceRatio
}
+ /**
+ * Important: the x and y is the location after exclude the nav bar and cutout
+ * */
fun distanceRatioFromLocationToClosableArea(x: Float, y: Float): Float {
+
val distanceToLocation = XMath.distance(
x1 = centerCloseBubbleX.toDouble(),
y1 = centerCloseBubbleY.toDouble(),
x2 = x.toDouble(),
y2 = y.toDouble()
)
- val distanceRatio = (closablePerimeterPx.toDouble() / distanceToLocation).let {
+ val distanceRatio = (builder.distanceToClosePx.toDouble() / distanceToLocation).let {
if (it > 1) return@let 0
return@let 1 - it
}.toFloat()
@@ -125,17 +113,17 @@ internal class FloatingCloseBubbleView(
} else {
val bubbleWidth = builder.bubbleView!!.width
- val centerBubbleX = (x + bubbleWidth/2)
+ val centerBubbleX = (x + bubbleWidth / 2)
- val isXOnTheLeft = centerBubbleX < halfScreenWidth
+ val isXOnTheLeft = centerBubbleX < halfSafeScreenWidth
windowParams.x = if (isXOnTheLeft) {
- baseX - ((halfScreenWidth - centerBubbleX) * distanceRatio) / 5
+ baseX - ((halfSafeScreenWidth - centerBubbleX) * distanceRatio) / 5
} else {
- baseX + ((centerBubbleX - halfScreenWidth) * distanceRatio) / 5
+ baseX + ((centerBubbleX - halfSafeScreenWidth) * distanceRatio) / 5
}.toInt()
- windowParams.y = baseY - (((ScreenEz.fullHeight - y) * distanceRatio) / 10)
+ windowParams.y = baseY - (((sez.fullHeight - y) * distanceRatio) / 10)
.toInt().let {
return@let if (it > LIMIT_FLY_HEIGHT) {
LIMIT_FLY_HEIGHT
diff --git a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/x.kt b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/x.kt
index e10fad5..f5d05bb 100644
--- a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/x.kt
+++ b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/x.kt
@@ -3,12 +3,10 @@ package com.torrydo.floatingbubbleview
import android.content.Context
import android.content.res.Resources
import android.graphics.Bitmap
-import android.graphics.Point
import android.util.Size
-import android.view.View
-import android.view.ViewTreeObserver
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toBitmap
+import com.torrydo.screenez.ScreenEasy
import java.lang.ref.WeakReference
@@ -27,8 +25,9 @@ internal fun Int.toBitmap(context: Context): Bitmap? {
}
}
-
-
internal fun Int.toDp(): Int = (this / Resources.getSystem().displayMetrics.density).toInt()
internal fun Int.toPx(): Int = (this * Resources.getSystem().displayMetrics.density).toInt()
+internal val sez = ScreenEasy()
+
+
diff --git a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/x_view.kt b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/x_view.kt
index 5886c7c..96b767b 100644
--- a/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/x_view.kt
+++ b/FloatingBubbleView/src/main/java/com/torrydo/floatingbubbleview/x_view.kt
@@ -7,16 +7,15 @@ import android.os.Build
import android.provider.Settings
import android.view.View
import android.view.ViewTreeObserver
-import com.torrydo.screenez.ScreenEz
// exclude view gesture on home screen -------------------------------------------------------------
private var exclusionRects: MutableList = ArrayList()
-internal fun View.updateGestureExclusion(context: Context) {
+internal fun View.updateGestureExclusion() {
if (Build.VERSION.SDK_INT < AndroidVersions.`10`) return
- val screenSize = ScreenEz.fullSize
+ val screenSize = sez.fullSize
exclusionRects.clear()
diff --git a/app/build.gradle b/app/build.gradle
index 52d0a75..1c8abec 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -54,7 +54,8 @@ dependencies {
// debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1'
implementation project(path: ':FloatingBubbleView')
-// implementation("io.github.torrydo:floating-bubble-view:0.4.0")
+// implementation("io.github.torrydo:floating-bubble-view:0.5.5")
+// implementation "io.github.torrydo:screen-easy:0.0.2"
def compose_version = "1.3.1"
implementation "androidx.compose.foundation:foundation:${compose_version}"
diff --git a/app/src/main/java/com/torrydo/testfloatingbubble/BubbleCompose.kt b/app/src/main/java/com/torrydo/testfloatingbubble/BubbleCompose.kt
index 8455779..a4e00b9 100644
--- a/app/src/main/java/com/torrydo/testfloatingbubble/BubbleCompose.kt
+++ b/app/src/main/java/com/torrydo/testfloatingbubble/BubbleCompose.kt
@@ -31,10 +31,15 @@ import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.runBlocking
@Composable
-fun BubbleCompose() {
+fun BubbleCompose(
+ show: () -> Unit,
+ hide: () -> Unit
+) {
val context = LocalContext.current
@@ -55,7 +60,13 @@ fun BubbleCompose() {
verticalAlignment = Alignment.CenterVertically
) {
IconButton(onClick = {
+ runBlocking {
+ hide()
+ delay(500)
+ show()
+ }
isPlay = isPlay.not()
+
}) {
Icon(
imageVector = if (isPlay) Icons.Default.PlayArrow else Icons.Default.Pause,
diff --git a/app/src/main/java/com/torrydo/testfloatingbubble/MyServiceKt.kt b/app/src/main/java/com/torrydo/testfloatingbubble/MyServiceKt.kt
index c50ad63..b59325d 100644
--- a/app/src/main/java/com/torrydo/testfloatingbubble/MyServiceKt.kt
+++ b/app/src/main/java/com/torrydo/testfloatingbubble/MyServiceKt.kt
@@ -10,7 +10,11 @@ import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.Toast
import androidx.core.app.NotificationCompat
-import com.torrydo.floatingbubbleview.*
+import com.torrydo.floatingbubbleview.BubbleBehavior
+import com.torrydo.floatingbubbleview.ExpandableView
+import com.torrydo.floatingbubbleview.FloatingBubble
+import com.torrydo.floatingbubbleview.FloatingBubbleService
+import com.torrydo.floatingbubbleview.Route
import com.torrydo.floatingbubbleview.viewx.ViewHelper
@@ -57,6 +61,7 @@ class MyServiceKt : FloatingBubbleService() {
Route.Bubble.name -> {
showBubbles()
}
+
Route.ExpandableView.name -> {
showExpandableView()
}
@@ -68,7 +73,7 @@ class MyServiceKt : FloatingBubbleService() {
private fun myNotification(
isVisible: Boolean
- ): Notification{
+ ): Notification {
val builder = NotificationCompat.Builder(this, channelId())
.setOngoing(true)
.setSmallIcon(R.drawable.ic_rounded_blue_diamond)
@@ -128,7 +133,7 @@ class MyServiceKt : FloatingBubbleService() {
val imgView = ViewHelper.fromDrawable(this, R.drawable.ic_rounded_blue_diamond, size, size)
-
+
imgView.setOnClickListener {
action.navigateToExpandableView()
}
@@ -139,7 +144,10 @@ class MyServiceKt : FloatingBubbleService() {
// .bubble(imgView)
// .bubble(v)
.bubble {
- BubbleCompose()
+ BubbleCompose(
+ show = {showBubbles()},
+ hide = {removeBubbles()}
+ )
}
// set style for bubble, fade animation by default
.bubbleStyle(null)
@@ -166,10 +174,10 @@ class MyServiceKt : FloatingBubbleService() {
// choose behavior of the bubbles
// DYNAMIC_CLOSE_BUBBLE: close-bubble moving based on the bubble's location
// FIXED_CLOSE_BUBBLE: bubble will automatically move to the close-bubble when it reaches the closable-area
- .behavior(BubbleBehavior.DYNAMIC_CLOSE_BUBBLE)
+ .behavior(BubbleBehavior.FIXED_CLOSE_BUBBLE)
// enable bottom background, false by default
- .bottomBackground(false)
+// .bottomBackground(true)
// add listener for the bubble
.addFloatingBubbleListener(object : FloatingBubble.Listener {
@@ -229,6 +237,8 @@ class MyServiceKt : FloatingBubbleService() {
// apply style for the expandable-view
.expandableViewStyle(null)
+// .drawUnderSystemUI(true)
+
// ddd listener for the expandable-view
.addExpandableViewListener(object : ExpandableView.Listener {
override fun onOpenExpandableView() {}
diff --git a/app/src/main/java/com/torrydo/testfloatingbubble/TestComposeView.kt b/app/src/main/java/com/torrydo/testfloatingbubble/TestComposeView.kt
index b23e9af..92ed34b 100644
--- a/app/src/main/java/com/torrydo/testfloatingbubble/TestComposeView.kt
+++ b/app/src/main/java/com/torrydo/testfloatingbubble/TestComposeView.kt
@@ -36,28 +36,29 @@ fun TestComposeView(
items.addAll(temp)
}
- Column(
- modifier = Modifier
- .padding(horizontal = 10.dp)
- .fillMaxWidth()
- .height(500.dp)
- .background(Color.LightGray),
- ) {
- Button(onClick = { popBack() }) {
- Text(text = "pop back!")
- }
- LazyColumn(
+ Column{
+ Column(
modifier = Modifier
.fillMaxWidth()
- .weight(1f)
+ .fillMaxHeight()
+ .background(Color.LightGray),
) {
- itemsIndexed(items) { index, item ->
- Row(
- modifier = Modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.Center,
- verticalAlignment = Alignment.CenterVertically
- ) {
- Text(text = item.toString(), fontSize = 18.sp)
+ Button(onClick = { popBack() }) {
+ Text(text = "pop back!")
+ }
+ LazyColumn(
+ modifier = Modifier
+ .fillMaxWidth()
+ .weight(1f)
+ ) {
+ itemsIndexed(items) { index, item ->
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.Center,
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text(text = item.toString(), fontSize = 18.sp)
+ }
}
}
}
diff --git a/gradle.properties b/gradle.properties
index bc3f95a..d835c44 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -27,13 +27,13 @@ RELEASE_SIGNING_ENABLED=true
GROUP=io.github.torrydo
POM_ARTIFACT_ID=floating-bubble-view
-VERSION_NAME=0.5.5
-#prev: 0.5.4
+VERSION_NAME=0.5.6
+#prev: 0.5.5
POM_NAME=FloatingBubbleView
POM_PACKAGING=aar
-POM_DESCRIPTION=an Android library that makes it easier to create floating bubbles.
+POM_DESCRIPTION=an Android library that adds floating views on top of your screen, supports both XML and Jetpack Compose.
POM_INCEPTION_YEAR=2022
POM_URL=https://github.com/TorryDo/Floating-Bubble-View