Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/torrydo/floating-bubble-view
πan Android library that adds floating views on top of your screenπ¨, supports both XML and Jetpack Compose
https://github.com/torrydo/floating-bubble-view
android-app android-java android-kotlin android-library android-service android-ui android-xml androidkotlin bubble chathead composable floating-bubbles floating-view floating-window jetpack-compose jetpack-compose-library kotlin-android kotlin-language
Last synced: about 9 hours ago
JSON representation
πan Android library that adds floating views on top of your screenπ¨, supports both XML and Jetpack Compose
- Host: GitHub
- URL: https://github.com/torrydo/floating-bubble-view
- Owner: TorryDo
- License: apache-2.0
- Created: 2021-12-16T12:19:19.000Z (almost 3 years ago)
- Default Branch: master
- Last Pushed: 2024-03-27T03:33:14.000Z (8 months ago)
- Last Synced: 2024-03-28T03:24:47.144Z (7 months ago)
- Topics: android-app, android-java, android-kotlin, android-library, android-service, android-ui, android-xml, androidkotlin, bubble, chathead, composable, floating-bubbles, floating-view, floating-window, jetpack-compose, jetpack-compose-library, kotlin-android, kotlin-language
- Language: Kotlin
- Homepage:
- Size: 2.86 MB
- Stars: 153
- Watchers: 3
- Forks: 28
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# πFloating Bubble View
An Android library that creates floating bubbles on top of the screen π¨, supports both XML and π Jetpack Compose
Like this project? π₯° Don't forget to show some love by giving a Starβ
| Bubble | Custom |
| :-: | :-: |
| | |[](https://www.android.com)
[](https://android-arsenal.com/api?level=21)
[]()
[](https://www.apache.org/licenses/LICENSE-2.0)Β
## Variants
- ### Flutter
If you are looking for a Flutter version of this library, check [dash_bubble](https://github.com/moazelsawaf/dash_bubble), a Flutter plugin that allows you to create a floating bubble on the screen. by [Moaz El-sawaf](https://github.com/moazelsawaf).## Table of Contents π
> 1. [Getting started](#getting_started)
> 2. [Setup](#setup)
> 3. [Usage](#usage)
> 4. [Contribution guide](#contribution_guide)
> 5. [WIP Note](#note) π§
> 6. [License](#license)## I, Getting started πππ
Ensure your appβs minimum SDK version is 21+ and `mavenCentral()` included
1. Ensure your appβs minimum SDK version is 21+. This is declared in the module-level `build.gradle` file
```gradle
android {
defaultConfig {
...
minSdk 21
}
```2. Ensure the `mavenCentral()` repository is declared in the project-level `build.gradle`/`setting.gradle` file:
settings.gradle
```gradle
pluginManagement {
repositories {
...
mavenCentral()
}
}
dependencyResolutionManagement {
...
repositories {
...
mavenCentral()
}
}
```
build.gradle (project-level) (on old gradle versions)
```gradle
allprojects {
repositories {
mavenCentral()
...
}
...
}
```
Declare the dependencies in the module-level `build.gradle` file π
```gradle
dependencies {
implementation("io.github.torrydo:floating-bubble-view:")
}
```### 1, extends `ExpandableBubbleService()` and call `expand()` or `minimize()` 1οΈβ£
Java
```java
Java docs is not completed yet because the author is (really) busy and (a little) tired πͺ
```Kotlin
```kotlin
class MyService: ExpandableBubbleService() {override fun onCreate() {
super.onCreate()
minimize()
}// optional, only required if you want to call minimize()
override fun configBubble(): BubbleBuilder? {
return ...
}// optional, only required if you want to call expand()
override fun configExpandedBubble(): ExpandedBubbleBuilder? {
return ...
}
}
```### 2, add bubble service to the manifest file 2οΈβ£
```xml
```
Android 13 and earlier
```xml
...
```
### 3, start bubble service and enjoy 3οΈβ£ ππ
> Make sure "display over other apps" permission is granted, otherwise the app will crash β βπ₯Java
```java
Intent intent = new Intent(context, MyService.class);
ContextCompat.startForegroundService(this, intent);
// or
// startService(intent); // for android version lower than 8.0 (android O)
// startForegroundService(intent); // for android 8.0 and higher
```Kotlin
```kotlin
val intent = Intent(context, MyService::class.java)
ContextCompat.startForegroundService(this, intent)
// or
// startService(intent) // for android version lower than 8.0 (android O)
// startForegroundService(intent) // for android 8.0 and higher
```### 1, `configBubble()` and `configExpandedBubble()`
Java
```java
public class MyServiceJava extends ExpandableBubbleService {@Override
public void onCreate() {
super.onCreate();
minimize();
}@Nullable
@Override
public BubbleBuilder configBubble() {
View imgView = ViewHelper.fromDrawable(this, R.drawable.ic_rounded_blue_diamond, 60, 60);
imgView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
expand();
}
});
return new BubbleBuilder(this)
.bubbleView(imgView)
.bubbleStyle(R.style.default_bubble_style)
.bubbleDraggable(true)
.forceDragging(true)
.closeBubbleView(ViewHelper.fromDrawable(this, R.drawable.ic_close_bubble))
.closeBubbleStyle(R.style.default_close_bubble_style)
.distanceToClose(100)
.triggerClickablePerimeterPx(5f)
.closeBehavior(CloseBubbleBehavior.FIXED_CLOSE_BUBBLE)
.startLocation(100, 100)
.enableAnimateToEdge(true)
.bottomBackground(false)
.addFloatingBubbleListener(new FloatingBubbleListener() {
@Override
public void onFingerDown(float x, float y) {}
@Override
public void onFingerUp(float x, float y) {}
@Override
public void onFingerMove(float x, float y) {}
})
;
}@Nullable
@Override
public ExpandedBubbleBuilder configExpandedBubble() {
View expandedView = LayoutInflater.from(this).inflate(R.layout.layout_view_test, null);expandedView.findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
minimize();
}
});
return new ExpandedBubbleBuilder(this)
.expandedView(expandedView)
.startLocation(0, 0)
.draggable(true)
.style(R.style.default_bubble_style)
.fillMaxWidth(true)
.enableAnimateToEdge(true)
.dimAmount(0.5f);
}
}
```Kotlin
```kotlin
class MyServiceKt : ExpandableBubbleService() {override fun onCreate() {
super.onCreate()
minimize()
}override fun configBubble(): BubbleBuilder? {
val imgView = ViewHelper.fromDrawable(this, R.drawable.ic_rounded_blue_diamond, 60, 60)
imgView.setOnClickListener {
expand()
}return BubbleBuilder(this)
// set bubble view
.bubbleView(imgView)
// or our sweetie, Jetpack Compose
.bubbleCompose {
BubbleCompose()
}
// set style for the bubble, fade animation by default
.bubbleStyle(null)
// set start location for the bubble, (x=0, y=0) is the top-left
.startLocation(100, 100) // in dp
.startLocationPx(100, 100) // in px
// enable auto animate bubble to the left/right side when release, true by default
.enableAnimateToEdge(true)
// set close-bubble view
.closeBubbleView(ViewHelper.fromDrawable(this, R.drawable.ic_close_bubble, 60, 60))
// set style for close-bubble, null by default
.closeBubbleStyle(null)
// DYNAMIC_CLOSE_BUBBLE: close-bubble moving based on the bubble's location
// FIXED_CLOSE_BUBBLE (default): bubble will automatically move to the close-bubble when it reaches the closable-area
.closeBehavior(CloseBubbleBehavior.DYNAMIC_CLOSE_BUBBLE)
// the more value (dp), the larger closeable-area
.distanceToClose(100)
// enable bottom background, false by default
.bottomBackground(true)
.addFloatingBubbleListener(object : FloatingBubbleListener {
override fun onFingerMove(x: Float, y: Float) {} // The location of the finger on the screen which triggers the movement of the bubble.
override fun onFingerUp(x: Float, y: Float) {} // ..., when finger release from bubble
override fun onFingerDown(x: Float, y: Float) {} // ..., when finger tap the bubble
})// set the clickable perimeter of the bubble in pixels (default = 5f)
.triggerClickablePerimeterPx(5f)}
override fun configExpandedBubble(): ExpandedBubbleBuilder? {
val expandedView = LayoutInflater.from(this).inflate(R.layout.layout_view_test, null)
expandedView.findViewById(R.id.btn).setOnClickListener {
minimize()
}return ExpandedBubbleBuilder(this)
.expandedView(expandedView)
.expandedCompose {
ExpandedCompose()
}
// handle key code
.onDispatchKeyEvent {
if(it.keyCode == KeyEvent.KEYCODE_BACK){
minimize()
}
null
}
// set start location in dp
.startLocation(0, 0)
// allow expanded bubble can be draggable or not
.draggable(true)
// fade animation by default
.style(null)
//
.fillMaxWidth(true)
// animate to the left/right side when release, trfalseue by default
.enableAnimateToEdge(true)
// set background dimmer
.dimAmount(0.6f)
}
}
```
### 2, Override default `Notification`
Java```java
public class MyService extends ExpandableBubbleService {
...
@Override
public void startNotificationForeground() {
startForeground(...);// or you can use NotificationHelper class
// val noti = NotificationHelper(this)
// noti.createNotificationChannel()
// startForeground(noti.notificationId, noti.defaultNotification())
}
}
```Kotlin
```kotlin
class MyService : FloatingBubbleService() {
...
// optional, of course
override fun startNotificationForeground() {
startForeground(...)// or you can use NotificationHelper class
// val noti = NotificationHelper(this)
// noti.createNotificationChannel()
// startForeground(noti.notificationId, noti.defaultNotification())
}
}
```Notice since Android 13 β
Starting in Android 13 (API level 33), notifications are only visible if the "POST_NOTIFICATIONS" permission is granted.
> The service will run normally even if the notification is not visible. π
> You still need to initialize the notification before showing any view.
### 3, Methods in `ExpandableBubbleService`
| Name | Description |
| :- | :- |
| `removeAll()` | remove all bubbles |
| `expand()` | show expanded-bubble |
| `minimize()` | show bubble |
| `enableBubbleDragging()` | enable bubble dragging or not |
| `enableExpandedBubbleDragging()` | enable expanded-bubble dragging or not |
| `animateBubbleToEdge()` | animate bubble to edge of the screen |
| `animateExpandedBubbleToEdge()` | animate expanded-bubble to edge of the screen |
### 4, Helper Class
- ViewHelper()
- fromBitmap(context, bitmap): View
- fromBitmap(context, bitmap, widthDp, heightDp): View
- fromDrawable(context, drawableRes): View
- fromDrawable(context, drawableRes, widthDp, heightDp)- NotificationHelper(context, channelId, channelName, notificationId)
- notify(Notification): update notification based on notificationId
- createNotificationChannel(): create notification channel from `android 8` and above
- defaultNotification(): return default notification## IV, Contribution Guide π
Contributions are welcome! π
- If you come across a bug or have an idea for a new feature, please let us know by creating an [Issue](https://github.com/TorryDo/Floating-Bubble-View/issues) ππ‘
- If you're interested in taking on an [open issue](https://github.com/TorryDo/Floating-Bubble-View/issues), please comment on it so others are aware π
- If you've already fixed a bug or implemented a feature, feel free to submit a [Pull request](https://github.com/TorryDo/Floating-Bubble-View/pulls) π
- Having questions, ideas, or feedback? Don't worry, I gotchu. Simply open a [Discussion](https://github.com/TorryDo/Floating-Bubble-View/discussions) π
- Find this project useful? π₯° Don't forget to show some love by giving a star βThank you! π
## V, Work in Progress π§
This library is still under heavy development. There is still a lot of code cleanup to do, so expect breaking API changes over time.Please refer to the following page to check out the change-log: [Releases](https://github.com/TorryDo/Floating-Bubble-View/releases)
Everything's gonna be ok! π
```
Copyright 2022 TorryDo
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 athttp://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.```