Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/leinardi/FloatingActionButtonSpeedDial

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)
https://github.com/leinardi/FloatingActionButtonSpeedDial

android android-library android-ui floatingactionbutton jetpack-compose material-design speed-dial

Last synced: 2 days ago
JSON representation

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)

Awesome Lists containing this project

README

        

# Floating Action Button Speed Dial
![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)
[![Travis](https://img.shields.io/travis/leinardi/FloatingActionButtonSpeedDial/master.svg)](https://travis-ci.org/leinardi/FloatingActionButtonSpeedDial)
[![GitHub license](https://img.shields.io/github/license/leinardi/FloatingActionButtonSpeedDial.svg)](https://github.com/leinardi/FloatingActionButtonSpeedDial/blob/master/LICENSE)
[![Stars](https://img.shields.io/github/stars/leinardi/FloatingActionButtonSpeedDial.svg?style=social&label=Stars)](https://github.com/leinardi/FloatingActionButtonSpeedDial/stargazers)

Android library providing an implementation of
the [Material Design Floating Action Button Speed Dial](https://material.io/guidelines/components/buttons-floating-action-button.html#buttons-floating-action-button-transitions)
for both classic View and Compose.

## Features

- [x] MinSdk 14 for Classic View and 21 for Compose
- [x] Highly customizable (label, icon, ripple, fab and label background colors, themes support)
- [x] Same animations as in [Inbox by Gmail](https://play.google.com/store/apps/details?id=com.google.android.apps.inbox)
- [x] Option to have different icons for open/close state
- [x] Optional overlay/touch guard layout
- [x] Support for bottom, left and right menu expansion (left and right have no labels)
- [x] Out-of-the box support for Snackbar behavior
- [x] Optional support for `RecyclerView` and `NestedScrollView` behavior
- [x] Support for VectorDrawable
- [x] Easy to use
- [x] Compose ready!

## How to use

### Gradle setup

#### Official releases

The library is available on Jcenter so no additional repository is required.

Dependencies 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)):

```groovy
// Compose only
implementation "com.leinardi.android:speed-dial.compose:1.0.0-alpha04"

// Classic View only
implementation "com.leinardi.android:speed-dial:3.3.0"
```

#### Snapshots (development branch)

You can use JitPack to test the latest `master` (remember that `master` is the development branch and can be unstable or completely broken).

Add the JitPack repository to your build file:

```groovy
maven { url 'https://jitpack.io' }
```

Add the dependency

```groovy
implementation 'com.github.leinardi:FloatingActionButtonSpeedDial:master-SNAPSHOT'
```

### Basic use for Compose

#### `SpeedDial`

Add the `SpeedDial()` Composable to the `floatingActionButton` of your `Scaffold`:

```kotlin
var speedDialState by rememberSaveable { mutableStateOf(SpeedDialState.Collapsed) }
var overlayVisible: Boolean by rememberSaveable { mutableStateOf(speedDialState.isExpanded()) }
Scaffold(
floatingActionButton = {
SpeedDial(
state = speedDialState,
onFabClick = { expanded ->
overlayVisible = !expanded
speedDialState = SpeedDialState(!expanded)
},
) {

}
}
) {
SpeedDialOverlay(
visible = overlayVisible,
onClick = {
overlayVisible = false
speedDialState = speedDialState.toggle()
},
)
}
```

#### Action items

Add the `FabWithLabel` items to the `SpeedDial`:

```kotlin
SpeedDial(
state = speedDialState,
onFabClick = { expanded ->
overlayVisible = !expanded
speedDialState = SpeedDialState(!expanded)
},
) {
item {
FabWithLabel(
onClick = { showToast(context, "Item 1 clicked!") },
labelContent = { Text(text = "Item 1") },
) {
Icon(Icons.Default.Share, null)
}
}
item {
FabWithLabel(
onClick = { showToast(context, "Item 2 clicked!") },
labelContent = { Text(text = "Item 2") },
) {
Icon(Icons.Default.Share, null)
}
}
}
```

### Basic use for Classic View

#### `SpeedDialView`

Add the `SpeedDialView` to your layout:

```xml

```

#### Action items

Add the items to the `SpeedDialView`:

```kotlin
val speedDialView = findViewById(R.id.speedDial)
speedDialView.addActionItem(
SpeedDialActionItem.Builder(R.id.fab_no_label, R.drawable.ic_link_white_24dp)
.create()
)
```

If the color customization is not requested, it is also possible to inflate the Action items form a Menu Resource:

```kotlin
speedDialView.inflate(R.menu.menu_speed_dial)
```

Only the attributes `android:id`, `android:icon` and `android:title` are supported.

#### Click listeners

Add the click listeners:

```kotlin
speedDialView.setOnActionSelectedListener(SpeedDialView.OnActionSelectedListener { actionItem ->
when (actionItem.id) {
R.id.fab_no_label -> {
showToast("No label action clicked!\nClosing with animation")
speedDialView.close() // To close the Speed Dial with animation
return@OnActionSelectedListener true // false will close it without animation
}
}
false
})
```

### Optional steps

#### Add the main action click listener

```kotlin
speedDialView.setOnChangeListener(object : SpeedDialView.OnChangeListener {
override fun onMainActionSelected(): Boolean {
showToast("Main action clicked!")
return false // True to keep the Speed Dial open
}

override fun onToggleChanged(isOpen: Boolean) {
Log.d(TAG, "Speed dial toggle state changed. Open = $isOpen")
}
})
```

#### Customizing the items

The `SpeedDialActionItem.Builder` provides several setters to customize the aspect of one item:

```kotlin
speedDialView.addActionItem(
SpeedDialActionItem.Builder(R.id.fab_custom_color, drawable)
.setFabBackgroundColor(ResourcesCompat.getColor(resources, R.color.material_white_1000, getTheme()))
.setFabImageTintColor(ResourcesCompat.getColor(resources, R.color.inbox_primary, getTheme()))
.setLabel(getString(R.string.label_custom_color))
.setLabelColor(Color.WHITE)
.setLabelBackgroundColor(ResourcesCompat.getColor(resources, R.color.inbox_primary, getTheme()))
.setLabelClickable(false)
.create()
)
```

It is also possible to specify a theme to easily change the FAB background and ripple effect color:

```kotlin
speedDialView.addActionItem(
SpeedDialActionItem.Builder(R.id.fab_custom_theme, R.drawable.ic_theme_white_24dp)
.setLabel(getString(R.string.label_custom_theme))
.setTheme(R.style.AppTheme_Purple)
.create()
)
```

```xml

<item name="colorPrimary">@color/material_purple_500</item>
<item name="colorPrimaryDark">@color/material_purple_700</item>
<item name="colorAccent">@color/material_purple_a700</item>
<item name="colorControlHighlight">@color/material_purple_200</item>

```

#### Adding an overlay/touch guard when the menu is open (like Inbox by Gmail)

You simply need to add the `SpeedDialOverlayLayout` to your layout:

```xml

```

and then provide the instance of that layout to the `SpeedDialView`:

```xml

```

or

```kotlin
val overlayLayout = findViewById(R.id.overlay)
speedDialView.setSpeedDialOverlayLayout(overlayLayout)
```

#### Hiding the FAB when scrolling a `RecyclerView` or a `NestedScrollView`

Just apply the `ScrollingViewSnackbarBehavior` to the `SpeedDialView`. This can be done via XML using the convenience string
resource `@string/speeddial_scrolling_view_snackbar_behavior`:

```xml

```

Or programmatically:

```kotlin
val params = speedDialView.layoutParams as CoordinatorLayout.LayoutParams
params.behavior = SpeedDialView.ScrollingViewSnackbarBehavior()
speedDialView.requestLayout()
```

NB: for the behaviors to work, `SpeedDialView` needs to be a direct child of `CoordinatorLayout`

#### Disabling `SnackbarBehavior`

Since the `SnackbarBehavior` is enabled by default and, afaik, it is not possible to remove a Behavior, simply use apply
the `SpeedDialView.NoBehavior` instead:

```kotlin
val params = speedDialView.layoutParams as CoordinatorLayout.LayoutParams
params.behavior = SpeedDialView.NoBehavior()
speedDialView.requestLayout()
```

### Sample project

A fully working example is available [here](/sample).

## Demo

### Video

https://www.youtube.com/watch?v=tWowiF5ElAg

### Sample app

[![Get it on the Play Store](/art/playstore_getiton.png)](https://play.google.com/store/apps/details?id=com.leinardi.android.speeddial.sample)

## Screenshots

### API 27, API 16, bottom and left expansion

## FAQ

### How can I create a new resource ID, required by the `SpeedDialActionItem.Builder`?

It can be done in XML using the ``:

```xml




```

### How can I change the maximum length of the label?

You can set a different value for the max length of the label overriding `sd_label_max_width`:

```
240dp
```

More info [here](https://developer.android.com/guide/topics/resources/more-resources.html#Id).

### How can I change the color of the overlay / touch guard layout?

The color of the `SpeedDialOverlayLayout` can be changed simply using the `android:background` attribute or, programmatically, using the equivalent
setter like any other view.

### How can I prevent the overlay / touch guard layout from going over the `Toolbar` inside a `CoordinatorLayout`?

It can be done using the attribute `app:layout_behavior="@string/appbar_scrolling_view_behavior"`:

```xml

```

## Changelog

See the [CHANGELOG.md](/CHANGELOG.md)

## Credits

This project is based on [floating-action-menu by ArthurGhazaryan](https://github.com/ArthurGhazaryan/floating-action-menu).

## Licenses

```
Copyright 2021 Roberto Leinardi.

Licensed to the Apache Software Foundation (ASF) under one or more contributor
license agreements. See the NOTICE file distributed with this work for
additional information regarding copyright ownership. The ASF licenses this
file to you 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.
```