Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

🍀 an Android library that adds floating views on top of your screen 🎨, supports both XML and Jetpack Compose

License

NotificationsYou must be signed in to change notification settings

dofire/Floating-Bubble-View

Repository files navigation

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⭐
BubbleCustom

 

Variants

  • Flutter

    If you are looking for a Flutter version of this library, checkdash_bubble, a Flutter plugin that allows you to create a floating bubble on the screen. byMoaz El-sawaf.

Table of Contents 📝

  1. Getting started
  2. Setup
  3. Usage
  4. Contribution guide
  5. WIP Note 🚧
  6. 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
android {    defaultConfig {...        minSdk21    }
  1. Ensure themavenCentral() repository is declared in the project-levelbuild.gradle/setting.gradle file:

    settings.gradle
    pluginManagement {    repositories {...        mavenCentral()    }}dependencyResolutionManagement {...    repositories {...        mavenCentral()    }}
    build.gradle (project-level) (on old gradle versions)
    allprojects {        repositories {            mavenCentral()...        }...    }

Declare the dependencies in the module-levelbuild.gradle file 🍀

dependencies {    implementation("io.github.torrydo:floating-bubble-view:<LATEST_VERSION>")}

II, Setup 🚀✈🛰

1, extendsExpandableBubbleService() and callexpand() orminimize() 1️⃣

Java
Javadocsisnotcompletedyetbecausetheauthoris (really)busyand (alittle)tired 😪
Kotlin
classMyService:ExpandableBubbleService() {overridefunonCreate() {super.onCreate()        minimize()    }// optional, only required if you want to call minimize()overridefunconfigBubble():BubbleBuilder? {return...   }// optional, only required if you want to call expand()overridefunconfigExpandedBubble():ExpandedBubbleBuilder? {return...   }}

2, add bubble service to the manifest file 2️⃣

<application><!-- these two permissions are added by default--><!-- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>--><!-- <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>--><!-- You can find more permissions, use cases here: https://developer.android.com/about/versions/14/changes/fgs-types-required-->     <uses-permissionandroid:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />          <serviceandroid:name="<YOUR_PACKAGE>.MyService"android:foregroundServiceType="specialUse"         >         <propertyandroid:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"android:value="foo"/><!-- optional-->     </service></application>
Android 13 and earlier
<!-- these two permissions are added by default--><!-- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>--><!-- <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>-->    <application>        ...        <serviceandroid:name="<YOUR_PACKAGE>.MyService" />    </application>

3, start bubble service and enjoy 3️⃣ 🎉🍀

Make sure "display over other apps" permission is granted, otherwise the app will crash ⚠❗💥

Java
Intentintent =newIntent(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
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

III, Usage 🔥

1,configBubble() andconfigExpandedBubble()

Java
publicclassMyServiceJavaextendsExpandableBubbleService {@OverridepublicvoidonCreate() {super.onCreate();minimize();    }@Nullable@OverridepublicBubbleBuilderconfigBubble() {ViewimgView =ViewHelper.fromDrawable(this,R.drawable.ic_rounded_blue_diamond,60,60);imgView.setOnClickListener(newView.OnClickListener() {@OverridepublicvoidonClick(Viewview) {expand();            }        });returnnewBubbleBuilder(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(newFloatingBubbleListener() {@OverridepublicvoidonFingerDown(floatx,floaty) {}@OverridepublicvoidonFingerUp(floatx,floaty) {}@OverridepublicvoidonFingerMove(floatx,floaty) {}                })                ;                    }@Nullable@OverridepublicExpandedBubbleBuilderconfigExpandedBubble() {ViewexpandedView =LayoutInflater.from(this).inflate(R.layout.layout_view_test,null);expandedView.findViewById(R.id.btn).setOnClickListener(newView.OnClickListener() {@OverridepublicvoidonClick(Viewview) {minimize();            }        });returnnewExpandedBubbleBuilder(this)                .expandedView(expandedView)                .startLocation(0,0)                .draggable(true)                .style(R.style.default_bubble_style)                .fillMaxWidth(true)                .enableAnimateToEdge(true)                .dimAmount(0.5f);    }}
Kotlin
classMyServiceKt :ExpandableBubbleService() {overridefunonCreate() {super.onCreate()        minimize()    }overridefunconfigBubble():BubbleBuilder? {val imgView=ViewHelper.fromDrawable(this,R.drawable.ic_rounded_blue_diamond,60,60)        imgView.setOnClickListener {            expand()        }returnBubbleBuilder(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 {overridefunonFingerMove(x:Float,y:Float) {}// The location of the finger on the screen which triggers the movement of the bubble.overridefunonFingerUp(x:Float,y:Float) {}// ..., when finger release from bubbleoverridefunonFingerDown(x:Float,y:Float) {}// ..., when finger tap the bubble            })// set the clickable perimeter of the bubble in pixels (default = 5f)            .triggerClickablePerimeterPx(5f)    }overridefunconfigExpandedBubble():ExpandedBubbleBuilder? {val expandedView=LayoutInflater.from(this).inflate(R.layout.layout_view_test,null)        expandedView.findViewById<View>(R.id.btn).setOnClickListener {            minimize()        }returnExpandedBubbleBuilder(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 defaultNotification

Java
publicclassMyServiceextendsExpandableBubbleService {    ...@OverridepublicvoidstartNotificationForeground() {startForeground(...);// or you can use NotificationHelper class// val noti = NotificationHelper(this)// noti.createNotificationChannel()// startForeground(noti.notificationId, noti.defaultNotification())    }}
Kotlin
classMyService :FloatingBubbleService() {...// optional, of courseoverridefunstartNotificationForeground() {        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 inExpandableBubbleService

NameDescription
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 fromandroid 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 anIssue 🐛💡
  • If you're interested in taking on anopen issue, please comment on it so others are aware 😊
  • If you've already fixed a bug or implemented a feature, feel free to submit aPull request 🚀
  • Having questions, ideas, or feedback? Don't worry, I gotchu. Simply open aDiscussion 🔊
  • 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

Everything's gonna be ok! 🍀


VI, License

    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 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.

[8]ページ先頭

©2009-2025 Movatter.jp