FAB Integration: CoordinatorLayout and Snackbar in Kotlin XML

In Android development using Kotlin and XML, CoordinatorLayout offers a robust framework for managing complex view interactions. Integrating a FloatingActionButton (FAB) with CoordinatorLayout and Snackbar can significantly enhance the user experience by providing contextual actions and feedback. This blog post explores how to effectively integrate these components for a cohesive and interactive UI.

Understanding the Components

  • CoordinatorLayout: A super-powered FrameLayout that coordinates animations, transitions, and interactions within its children. It enables complex behaviors like scrolling effects and view dependencies.
  • FloatingActionButton (FAB): A prominent round button that typically represents the primary action within a screen.
  • Snackbar: A lightweight, transient UI element used to provide brief feedback to the user, usually displayed at the bottom of the screen.

Why Integrate FAB, CoordinatorLayout, and Snackbar?

  • Contextual Actions: FAB provides immediate access to primary actions based on the context.
  • Coordinated Interactions: CoordinatorLayout ensures smooth transitions and interactions between FAB and other views.
  • User Feedback: Snackbar provides instant feedback on actions performed, enhancing usability.

Implementation Steps

Step 1: Setting Up the Project

Create a new Android project in Android Studio with Kotlin support or open an existing project. Ensure that you have the AndroidX dependencies configured.

Step 2: Adding Dependencies

Include the necessary Material Components dependency in your build.gradle file to use FloatingActionButton and Snackbar.


dependencies {
    implementation("com.google.android.material:material:1.6.0") // or newer
}

Sync the Gradle project to apply the changes.

Step 3: Designing the Layout (XML)

Open your layout file (e.g., activity_main.xml) and add the CoordinatorLayout, AppBarLayout, RecyclerView (or any content view), and FloatingActionButton.


<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp"
        android:src="@android:drawable/ic_input_add"
        app:elevation="6dp"
        app:pressedTranslationZ="12dp"
        app:layout_anchorGravity="bottom|end" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Explanation:

  • CoordinatorLayout: Encloses the entire layout, enabling coordinated behaviors between child views.
  • AppBarLayout and Toolbar: Creates an app bar that can collapse or expand based on scrolling, handled by the layout_scrollFlags.
  • RecyclerView: Represents a scrollable list, with its scrolling behavior coordinated with the AppBarLayout via app:layout_behavior.
  • FloatingActionButton: Added to the layout with layout_gravity positioning it to the bottom-end and margins providing spacing. The app:layout_anchorGravity is important as if defines its behaviour upon screen rotation

Step 4: Implementing the Logic in Kotlin

In your MainActivity.kt file, handle the FAB click event and display a Snackbar.


import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.snackbar.Snackbar
import androidx.appcompat.widget.Toolbar

class MainActivity : AppCompatActivity() {

    private lateinit var recyclerView: RecyclerView
    private lateinit var fab: FloatingActionButton
    private lateinit var toolbar: Toolbar

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        toolbar = findViewById(R.id.toolbar)
        setSupportActionBar(toolbar)

        recyclerView = findViewById(R.id.recyclerView)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = SimpleItemAdapter((1..20).map { "Item $it" }) // Replace with your data

        fab = findViewById(R.id.fab)
        fab.setOnClickListener { view ->
            Snackbar.make(view, "FAB Clicked!", Snackbar.LENGTH_LONG)
                .setAction("Action", null)
                .show()
        }
    }
}

class SimpleItemAdapter(private val items: List) : RecyclerView.Adapter() {

    class ViewHolder(val itemView: android.view.View) : RecyclerView.ViewHolder(itemView) {
        val textView = itemView.findViewById<android.widget.TextView>(android.R.id.text1)!!
    }

    override fun onCreateViewHolder(parent: android.view.ViewGroup, viewType: Int): ViewHolder {
        val view = android.view.LayoutInflater.from(parent.context).inflate(android.R.layout.simple_list_item_1, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.textView.text = items[position]
    }

    override fun getItemCount() = items.size
}

Explanation:

  • The FAB’s click listener shows a Snackbar with a message when the FAB is clicked.
  • Snackbar.make() creates the Snackbar associated with the CoordinatorLayout, enabling automatic positioning above the FAB.

Step 5: Testing the Integration

Run the application on an emulator or a physical device.

  1. Verify that the FAB is positioned correctly at the bottom-end of the screen.
  2. Click the FAB to display the Snackbar. It should appear above the FAB, handled automatically by the CoordinatorLayout.
  3. Test the scrolling behavior. The AppBarLayout should collapse or expand as the RecyclerView is scrolled.

Advanced Behaviors

Hiding FAB on Scroll

To hide the FAB when the RecyclerView is scrolled, implement a custom AppBarLayout.OnOffsetChangedListener or use a pre-built behavior.


import com.google.android.material.appbar.AppBarLayout

class MainActivity : AppCompatActivity() {

    // ... other parts of the class

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // ... other initializations

        val appBarLayout: AppBarLayout = findViewById(R.id.appbar)

        appBarLayout.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
            if (Math.abs(verticalOffset) > 200) { // Adjust threshold as needed
                fab.hide()
            } else {
                fab.show()
            }
        })
    }
}

In this example, the FAB hides when the AppBarLayout is scrolled a certain distance, and it reappears when scrolled back.

Conclusion

Integrating a FloatingActionButton with CoordinatorLayout and Snackbar in Kotlin and XML enhances the user experience by providing contextual actions and feedback. Using the CoordinatorLayout ensures coordinated animations and transitions, making your Android application more interactive and user-friendly. Understanding these components and their interactions will help you create sophisticated and engaging UIs.