Adding a floating action button to an Android app
A FloatingActionButton, commonly shortened to FAB, gives users a prominent shortcut for a primary action such as creating a note, adding a transaction, composing a message or saving a new record. In an Android project using XML layouts, the Material Components library provides a ready-made circular button with elevation, ripple feedback and support for icons.
This guide shows how to add a FAB, connect it to Kotlin code and make the interaction useful. The example uses a notes screen, although the same pattern works for SQLite records, shopping lists and appointment apps used by people in Sydney, Melbourne or regional Australian areas.
| Approach | Best for | Main advantage | Key consideration |
|---|---|---|---|
| Material XML FAB | View-based Android projects | Simple to add to an existing layout | Requires correct CoordinatorLayout placement |
| Extended FAB | Actions needing a text label | Clearer purpose for new users | Uses more screen space |
| Jetpack Compose FAB | Modern Compose applications | Declarative UI and concise code | Needs Compose-specific layout code |
| ImageButton | Small secondary actions | Flexible visual styling | Lacks the standard FAB treatment |
Add the Material dependency
First, check that the app module can use Material Components. In app/build.gradle.kts, add the dependency below. Use the latest stable version available in your project rather than copying an old version from an outdated tutorial.
dependencies {
implementation("com.google.android.material:material:1.12.0")
}
Sync Gradle after saving the file. Your app theme should inherit from a Material theme, such as Theme.Material3.DayNight.NoActionBar, in themes.xml. Material 3 provides modern colours, shape styling and accessibility behaviour that fit well with current Android releases.
If your project still uses an AppCompat theme, the button can work, but colour attributes may not behave as expected. Updating the theme before styling the control prevents confusing results, particularly when supporting both light and dark mode.
Create the floating action button layout
A CoordinatorLayout is a useful parent because it allows the FAB to sit above content and work neatly with snackbars, bottom sheets and scrolling components. Place the button near the end of the layout so it is easy to find.
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/notesList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/addNoteButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:contentDescription="@string/add_note"
android:src="@drawable/ic_add"
app:backgroundTint="@color/purple_500"
app:tint="@android:color/white" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Define the content description in res/values/strings.xml:
<string name="add_note">Add a new note</string>
A content description is essential because TalkBack users may not see the plus icon. Keep the icon itself simple and use a vector drawable where possible. A white plus symbol on a sufficiently contrasting background is easier to recognise in bright outdoor conditions, including the strong sunlight common in Perth or Brisbane.
Connect the button to Kotlin
In the activity or fragment that owns the layout, find the FAB and attach a click listener. The example opens a note editor, but you could instead insert a row into SQLite, display a dialog or navigate to a new screen.
class NotesActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_notes)
val addNoteButton = findViewById<FloatingActionButton>(R.id.addNoteButton)
addNoteButton.setOnClickListener {
startActivity(Intent(this, EditNoteActivity::class.java))
}
}
}
Add the required imports:
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.floatingactionbutton.FloatingActionButton
If the action completes without opening another screen, provide immediate feedback. For example, a snackbar can confirm that a record was saved. This is more informative than silently changing a list, especially for users checking an app while commuting on Sydney trains or Melbourne trams.
Snackbar.make(
addNoteButton,
R.string.note_saved,
Snackbar.LENGTH_SHORT
).show()
Position the button around other content
A FAB should float above the main content without covering important controls. For a RecyclerView, leave enough bottom padding for the final list item to remain visible above the button. If the screen contains a bottom navigation bar, increase the bottom margin or use a ConstraintLayout with a clear anchor.
On devices with gesture navigation, edge-to-edge layouts can place the control too close to the system navigation area. Window insets should be applied when your app draws behind system bars. This matters on newer phones and tablets, where safe spacing varies between models.
An extended FAB may be a better choice when the action is unfamiliar:
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/addNoteButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:text="@string/add_note"
app:icon="@drawable/ic_add" />
Use a regular circular button for a familiar single action. Use an extended version when the label reduces ambiguity, such as “Add expense” in a budgeting app.
Choose colours and icons carefully
The FAB usually represents the primary action on a screen, so its colour should come from the app’s theme rather than an arbitrary bright value. Material theme attributes make the control adapt to light and dark appearance settings.
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/addNoteButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/add_note"
app:backgroundTint="?attr/colorPrimary"
app:tint="?attr/colorOnPrimary"
app:srcCompat="@drawable/ic_add" />
Check contrast, touch size and icon meaning. The button should provide a touch target of at least 48dp, and the plus icon should not be so detailed that it becomes unclear at smaller sizes. Test both portrait and landscape layouts, including smaller Android devices still used across the Australian market.
Handle repeated taps and state changes
Users may tap repeatedly if an operation takes time. Disable the FAB while a note is being saved, then enable it after the database or network operation finishes. This helps prevent duplicate SQLite rows or repeated server requests.
addNoteButton.setOnClickListener {
addNoteButton.isEnabled = false
lifecycleScope.launch {
viewModel.saveNote()
addNoteButton.isEnabled = true
Snackbar.make(
addNoteButton,
R.string.note_saved,
Snackbar.LENGTH_SHORT
).show()
}
}
For a long-running task, show progress elsewhere rather than leaving the user uncertain. Apps used in regional Australia may encounter weaker mobile coverage than those used in inner Melbourne or Sydney, so network actions should handle delays and failures gracefully. A retry message is preferable to creating duplicate content.
Test accessibility, privacy and local behaviour
Test the FAB with TalkBack, keyboard navigation, large font settings and dark mode. Confirm that the label describes the action, that focus reaches the control in a sensible order and that the button remains visible when text size is increased. Automated accessibility checks in Android Studio can identify missing descriptions and contrast issues.
If the button creates accounts, stores location data or uploads personal notes, explain the data use clearly. Australian developers should consider obligations under the Privacy Act 1988 and the Australian Privacy Principles when collecting personal information. Avoid requesting unrelated permissions just because a future feature may need them.
Finally, test on a range of screen sizes and connection conditions before publishing through Google Play. Use Australian English where appropriate, display Australian dollar amounts with suitable formatting in finance apps, and account for local time zones when a new record receives a timestamp. A carefully positioned FAB is a small interface element, but it can make a daily action faster, clearer and more dependable.