{"id":15132448,"url":"https://github.com/leinardi/FloatingActionButtonSpeedDial","last_synced_at":"2025-09-29T00:32:03.063Z","repository":{"id":31113294,"uuid":"126714653","full_name":"leinardi/FloatingActionButtonSpeedDial","owner":"leinardi","description":"A Floating Action Button Speed Dial implementation for Android that follows the Material Design specification (https://material.io/components/buttons-floating-action-button#types-of-transitions)","archived":false,"fork":false,"pushed_at":"2024-04-04T07:35:37.000Z","size":2395,"stargazers_count":1476,"open_issues_count":44,"forks_count":146,"subscribers_count":35,"default_branch":"release","last_synced_at":"2025-09-26T12:49:41.430Z","etag":null,"topics":["android","android-library","android-ui","floatingactionbutton","jetpack-compose","material-design","speed-dial"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leinardi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-25T16:01:47.000Z","updated_at":"2025-09-19T02:06:21.000Z","dependencies_parsed_at":"2024-04-04T08:47:24.746Z","dependency_job_id":null,"html_url":"https://github.com/leinardi/FloatingActionButtonSpeedDial","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/leinardi/FloatingActionButtonSpeedDial","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leinardi%2FFloatingActionButtonSpeedDial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leinardi%2FFloatingActionButtonSpeedDial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leinardi%2FFloatingActionButtonSpeedDial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leinardi%2FFloatingActionButtonSpeedDial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leinardi","download_url":"https://codeload.github.com/leinardi/FloatingActionButtonSpeedDial/tar.gz/refs/heads/release","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leinardi%2FFloatingActionButtonSpeedDial/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277450938,"owners_count":25819971,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-28T02:00:08.834Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-library","android-ui","floatingactionbutton","jetpack-compose","material-design","speed-dial"],"created_at":"2024-09-26T04:04:45.939Z","updated_at":"2025-09-29T00:32:02.628Z","avatar_url":"https://github.com/leinardi.png","language":"Java","readme":"# Floating Action Button Speed Dial\n![Maven Central Compose](https://img.shields.io/maven-central/v/com.leinardi.android/speed-dial.compose?label=Compose)\n![Maven Central View](https://img.shields.io/maven-central/v/com.leinardi.android/speed-dial?label=View)\n[![Travis](https://img.shields.io/travis/leinardi/FloatingActionButtonSpeedDial/master.svg)](https://travis-ci.org/leinardi/FloatingActionButtonSpeedDial)\n[![GitHub license](https://img.shields.io/github/license/leinardi/FloatingActionButtonSpeedDial.svg)](https://github.com/leinardi/FloatingActionButtonSpeedDial/blob/master/LICENSE)\n[![Stars](https://img.shields.io/github/stars/leinardi/FloatingActionButtonSpeedDial.svg?style=social\u0026label=Stars)](https://github.com/leinardi/FloatingActionButtonSpeedDial/stargazers)\n\n\n\u003cimg src=\"/art/demo_1.gif\" width=\"290\" align=\"right\" hspace=\"0\" /\u003e\n\nAndroid library providing an implementation of\nthe [Material Design Floating Action Button Speed Dial](https://material.io/guidelines/components/buttons-floating-action-button.html#buttons-floating-action-button-transitions)\nfor both classic View and Compose.\n\n## Features\n\n- [x] MinSdk 14 for Classic View and 21 for Compose\n- [x] Highly customizable (label, icon, ripple, fab and label background colors, themes support)\n- [x] Same animations as in [Inbox by Gmail](https://play.google.com/store/apps/details?id=com.google.android.apps.inbox)\n- [x] Option to have different icons for open/close state\n- [x] Optional overlay/touch guard layout\n- [x] Support for bottom, left and right menu expansion (left and right have no labels)\n- [x] Out-of-the box support for Snackbar behavior\n- [x] Optional support for `RecyclerView` and `NestedScrollView` behavior\n- [x] Support for VectorDrawable\n- [x] Easy to use\n- [x] Compose ready!\n\n## How to use\n\n### Gradle setup\n\n#### Official releases\n\nThe library is available on Jcenter so no additional repository is required.\n\nDependencies entry (latest version on Maven Central ![Maven Central Compose](https://img.shields.io/maven-central/v/com.leinardi.android/speed-dial.compose?label=Compose) ![Maven Central View](https://img.shields.io/maven-central/v/com.leinardi.android/speed-dial?label=View)):\n\n```groovy\n// Compose only\nimplementation \"com.leinardi.android:speed-dial.compose:1.0.0-alpha04\"\n\n// Classic View only\nimplementation \"com.leinardi.android:speed-dial:3.3.0\"\n```\n\n#### Snapshots (development branch)\n\nYou can use JitPack to test the latest `master` (remember that `master` is the development branch and can be unstable or completely broken).\n\nAdd the JitPack repository to your build file:\n\n```groovy\nmaven { url 'https://jitpack.io' }\n```\n\nAdd the dependency\n\n```groovy\nimplementation 'com.github.leinardi:FloatingActionButtonSpeedDial:master-SNAPSHOT'\n```\n\n### Basic use for Compose\n\n#### `SpeedDial`\n\nAdd the `SpeedDial()` Composable to the `floatingActionButton` of your `Scaffold`:\n\n```kotlin\nvar speedDialState by rememberSaveable { mutableStateOf(SpeedDialState.Collapsed) }\nvar overlayVisible: Boolean by rememberSaveable { mutableStateOf(speedDialState.isExpanded()) }\nScaffold(\n    floatingActionButton = {\n        SpeedDial(\n            state = speedDialState,\n            onFabClick = { expanded -\u003e\n                overlayVisible = !expanded\n                speedDialState = SpeedDialState(!expanded)\n            },\n        ) {\n\n        }\n    }\n) {\n    SpeedDialOverlay(\n        visible = overlayVisible,\n        onClick = {\n            overlayVisible = false\n            speedDialState = speedDialState.toggle()\n        },\n    )\n}\n```\n\n#### Action items\n\nAdd the `FabWithLabel` items to the `SpeedDial`:\n\n```kotlin\n SpeedDial(\n    state = speedDialState,\n    onFabClick = { expanded -\u003e\n        overlayVisible = !expanded\n        speedDialState = SpeedDialState(!expanded)\n    },\n) {\n    item {\n        FabWithLabel(\n            onClick = { showToast(context, \"Item 1 clicked!\") },\n            labelContent = { Text(text = \"Item 1\") },\n        ) {\n            Icon(Icons.Default.Share, null)\n        }\n    }\n    item {\n        FabWithLabel(\n            onClick = { showToast(context, \"Item 2 clicked!\") },\n            labelContent = { Text(text = \"Item 2\") },\n        ) {\n            Icon(Icons.Default.Share, null)\n        }\n    }\n}\n```\n\n### Basic use for Classic View\n\n#### `SpeedDialView`\n\nAdd the `SpeedDialView` to your layout:\n\n```xml\n\n\u003ccom.leinardi.android.speeddial.SpeedDialView android:id=\"@+id/speedDial\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:layout_gravity=\"bottom|end\" app:sdMainFabClosedSrc=\"@drawable/ic_add_white_24dp\" /\u003e\n```\n\n#### Action items\n\nAdd the items to the `SpeedDialView`:\n\n```kotlin\nval speedDialView = findViewById\u003cSpeedDialView\u003e(R.id.speedDial)\nspeedDialView.addActionItem(\n    SpeedDialActionItem.Builder(R.id.fab_no_label, R.drawable.ic_link_white_24dp)\n        .create()\n)\n```\n\nIf the color customization is not requested, it is also possible to inflate the Action items form a Menu Resource:\n\n```kotlin\nspeedDialView.inflate(R.menu.menu_speed_dial)\n```\n\nOnly the attributes `android:id`, `android:icon` and `android:title` are supported.\n\n#### Click listeners\n\nAdd the click listeners:\n\n```kotlin\nspeedDialView.setOnActionSelectedListener(SpeedDialView.OnActionSelectedListener { actionItem -\u003e\n    when (actionItem.id) {\n        R.id.fab_no_label -\u003e {\n            showToast(\"No label action clicked!\\nClosing with animation\")\n            speedDialView.close() // To close the Speed Dial with animation\n            return@OnActionSelectedListener true // false will close it without animation\n        }\n    }\n    false\n})\n```\n\n### Optional steps\n\n#### Add the main action click listener\n\n```kotlin\nspeedDialView.setOnChangeListener(object : SpeedDialView.OnChangeListener {\n    override fun onMainActionSelected(): Boolean {\n        showToast(\"Main action clicked!\")\n        return false // True to keep the Speed Dial open\n    }\n\n    override fun onToggleChanged(isOpen: Boolean) {\n        Log.d(TAG, \"Speed dial toggle state changed. Open = $isOpen\")\n    }\n})\n```\n\n#### Customizing the items\n\nThe `SpeedDialActionItem.Builder` provides several setters to customize the aspect of one item:\n\n```kotlin\nspeedDialView.addActionItem(\n    SpeedDialActionItem.Builder(R.id.fab_custom_color, drawable)\n        .setFabBackgroundColor(ResourcesCompat.getColor(resources, R.color.material_white_1000, getTheme()))\n        .setFabImageTintColor(ResourcesCompat.getColor(resources, R.color.inbox_primary, getTheme()))\n        .setLabel(getString(R.string.label_custom_color))\n        .setLabelColor(Color.WHITE)\n        .setLabelBackgroundColor(ResourcesCompat.getColor(resources, R.color.inbox_primary, getTheme()))\n        .setLabelClickable(false)\n        .create()\n)\n```\n\nIt is also possible to specify a theme to easily change the FAB background and ripple effect color:\n\n```kotlin\nspeedDialView.addActionItem(\n    SpeedDialActionItem.Builder(R.id.fab_custom_theme, R.drawable.ic_theme_white_24dp)\n        .setLabel(getString(R.string.label_custom_theme))\n        .setTheme(R.style.AppTheme_Purple)\n        .create()\n)\n```\n\n```xml\n\n\u003cstyle name=\"AppTheme.Purple\" parent=\"AppTheme\"\u003e\n    \u003citem name=\"colorPrimary\"\u003e@color/material_purple_500\u003c/item\u003e\n    \u003citem name=\"colorPrimaryDark\"\u003e@color/material_purple_700\u003c/item\u003e\n    \u003citem name=\"colorAccent\"\u003e@color/material_purple_a700\u003c/item\u003e\n    \u003citem name=\"colorControlHighlight\"\u003e@color/material_purple_200\u003c/item\u003e\n\u003c/style\u003e\n```\n\n#### Adding an overlay/touch guard when the menu is open (like Inbox by Gmail)\n\nYou simply need to add the `SpeedDialOverlayLayout` to your layout:\n\n```xml\n\n\u003ccom.leinardi.android.speeddial.SpeedDialOverlayLayout android:id=\"@+id/overlay\" android:layout_width=\"match_parent\" android:layout_height=\"match_parent\" /\u003e\n```\n\nand then provide the instance of that layout to the `SpeedDialView`:\n\n```xml\n\n\u003ccom.leinardi.android.speeddial.SpeedDialView android:id=\"@+id/speedDial\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" app:sdMainFabClosedSrc=\"@drawable/ic_add_white_24dp\" app:sdOverlayLayout=\"@id/overlay\" /\u003e\n```\n\nor\n\n```kotlin\nval overlayLayout = findViewById\u003cSpeedDialOverlayLayout\u003e(R.id.overlay)\nspeedDialView.setSpeedDialOverlayLayout(overlayLayout)\n```\n\n#### Hiding the FAB when scrolling a `RecyclerView` or a `NestedScrollView`\n\nJust apply the `ScrollingViewSnackbarBehavior` to the `SpeedDialView`. This can be done via XML using the convenience string\nresource `@string/speeddial_scrolling_view_snackbar_behavior`:\n\n```xml\n\n\u003ccom.leinardi.android.speeddial.SpeedDialView android:id=\"@+id/speedDial\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" app:layout_behavior=\"@string/speeddial_scrolling_view_snackbar_behavior\" /\u003e\n```\n\nOr programmatically:\n\n```kotlin\nval params = speedDialView.layoutParams as CoordinatorLayout.LayoutParams\nparams.behavior = SpeedDialView.ScrollingViewSnackbarBehavior()\nspeedDialView.requestLayout()\n```\n\nNB: for the behaviors to work, `SpeedDialView` needs to be a direct child of `CoordinatorLayout`\n\n#### Disabling `SnackbarBehavior`\n\nSince the `SnackbarBehavior` is enabled by default and, afaik, it is not possible to remove a Behavior, simply use apply\nthe `SpeedDialView.NoBehavior` instead:\n\n```kotlin\nval params = speedDialView.layoutParams as CoordinatorLayout.LayoutParams\nparams.behavior = SpeedDialView.NoBehavior()\nspeedDialView.requestLayout()\n```\n\n### Sample project\n\nA fully working example is available [here](/sample).\n\n## Demo\n\n### Video\n\nhttps://www.youtube.com/watch?v=tWowiF5ElAg\n\n### Sample app\n\n[![Get it on the Play Store](/art/playstore_getiton.png)](https://play.google.com/store/apps/details?id=com.leinardi.android.speeddial.sample)\n\n## Screenshots\n\n### API 27, API 16, bottom and left expansion\n\n\u003cimg src=\"/art/screenshot_api_27.png\" width=\"215\"/\u003e \u003cimg src=\"/art/screenshot_api_16.png\" width=\"215\"/\u003e \u003cimg src=\"/art/screenshot_api_27_top_fab_bottom_expansion.png\" width=\"215\"/\u003e \u003cimg src=\"/art/screenshot_api_27_bottom_fab_left_expansion.png\" width=\"215\"/\u003e\n\n## FAQ\n\n### How can I create a new resource ID, required by the `SpeedDialActionItem.Builder`?\n\nIt can be done in XML using the `\u003citem type=\"id\" /\u003e`:\n\n```xml\n\n\u003cresources\u003e\n    \u003citem name=\"fab_action1\" type=\"id\" /\u003e\n    \u003citem name=\"fab_action2\" type=\"id\" /\u003e\n    \u003citem name=\"fab_action3\" type=\"id\" /\u003e\n    \u003citem name=\"fab_action4\" type=\"id\" /\u003e\n\u003c/resources\u003e\n```\n\n### How can I change the maximum length of the label?\n\nYou can set a different value for the max length of the label overriding `sd_label_max_width`:\n\n```\n\u003cdimen name=\"sd_label_max_width\"\u003e240dp\u003c/dimen\u003e\n```\n\nMore info [here](https://developer.android.com/guide/topics/resources/more-resources.html#Id).\n\n### How can I change the color of the overlay / touch guard layout?\n\nThe color of the `SpeedDialOverlayLayout` can be changed simply using the `android:background` attribute or, programmatically, using the equivalent\nsetter like any other view.\n\n### How can I prevent the overlay / touch guard layout from going over the `Toolbar` inside a `CoordinatorLayout`?\n\nIt can be done using the attribute `app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"`:\n\n```xml\n\n\u003ccom.leinardi.android.speeddial.SpeedDialOverlayLayout android:id=\"@+id/overlay\" android:layout_width=\"match_parent\" android:layout_height=\"match_parent\" app:layout_behavior=\"@string/appbar_scrolling_view_behavior\" /\u003e\n```\n\n## Changelog\n\nSee the [CHANGELOG.md](/CHANGELOG.md)\n\n## Credits\n\nThis project is based on [floating-action-menu by ArthurGhazaryan](https://github.com/ArthurGhazaryan/floating-action-menu).\n\n## Licenses\n\n```\nCopyright 2021 Roberto Leinardi.\n\nLicensed to the Apache Software Foundation (ASF) under one or more contributor\nlicense agreements.  See the NOTICE file distributed with this work for\nadditional information regarding copyright ownership.  The ASF licenses this\nfile to you under the Apache License, Version 2.0 (the \"License\"); you may not\nuse this file except in compliance with the License.  You may obtain a copy of\nthe License at\n\n  http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\nWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the\nLicense for the specific language governing permissions and limitations under\nthe License.\n```\n","funding_links":[],"categories":["Libraries"],"sub_categories":["UI"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleinardi%2FFloatingActionButtonSpeedDial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleinardi%2FFloatingActionButtonSpeedDial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleinardi%2FFloatingActionButtonSpeedDial/lists"}