Chris
Chris

Reputation: 13

Prevent Snackbar Overlap with FloatingActionButton in ConstraintLayout of Activity's Child Fragment

This is my current Setup:

I have a BaseActivity that registers the snackbar on the root layout (CoordinatorLayout):

<?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"
    android:id="@+id/snackbar_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_dodgeInsetEdges="bottom">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/app_bar_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <include layout="@layout/toolbar" />
        </com.google.android.material.appbar.AppBarLayout>

        <include layout="@layout/progressbar_with_text" />

        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/main"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

now i add a fragment which looks like this:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab_save"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/content_save"
        android:tint="@android:color/white"
        android:visibility="gone"
        app:backgroundTint="@color/secondary"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:tint="@android:color/white"
        app:useCompatPadding="true"
        tools:ignore="SpeakableTextPresentCheck"
        tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

I want the fab to be pushed up by the snackbar when shown, currently it gets overlapped from the snackbar.

I understand that using a CoordinatorLayout as the root and placing the FloatingActionButton (FAB) inside it works well with the attribute app:layout_dodgeInsetEdges="bottom". This setup ensures the FAB is pushed up when a Snackbar is shown. However, with a child fragment, I'm unable to achieve a similar result. And yes, it's essential for my setup to remain as is because I have multiple fragments that differ from each other and contain uniquely styled FABs, so moving the FAB to the activity level isn't an option.

Upvotes: 1

Views: 56

Answers (1)

Akshay
Akshay

Reputation: 71

You should create a method in your BaseActivity to show a snackbar, inside this method find the coordinatorLayout by its id.

public void showSnackbar(String message, int duration) {
    CoordinatorLayout coordinatorLayout = findViewById(R.id.snackbar_container);
    Snackbar.make(coordinatorLayout, message, duration).show();
}

your fragments should have access to the BaseActivity.Make sure your activity implements a certain interface, which will allow fragments to communicate with the activity.

public class MyFragment extends Fragment {

    private BaseActivity activity;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof BaseActivity) {
            activity = (BaseActivity) context;
        }
    }

    private void showSnackbar(String message) {
        activity.showSnackbar(message, Snackbar.LENGTH_SHORT);
    }
}

Upvotes: 0

Related Questions