Search code examples
androidandroid-coordinatorlayout

Why doesn't CoordinatorLayout release space for Snackbar messsage in Android Studio?


I know that CoordinatorLayout will release some space and let Snackbar display message at the bottom of screen normally.

In the following code, the AppCompatActivity layout layout_main.xml load a Fragment layout layout_home.xml.

layout_main.xml is CoordinatorLayout, I think the CoordinatorLayout will release space for Snackbar messsage when I click btnStart button.

But in fact, the CoordinatorLayout doesn't release space for Snackbar messsage, you can see Image A.

What is the problem with my code?

ActivityMain.kt

class ActivityMain : AppCompatActivity() {

    private lateinit var binding: LayoutMainBinding  
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.layout_main)

    }
}

FragmentHome.kt

class FragmentHome : Fragment() {

    private lateinit var binding: LayoutHomeBinding

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = DataBindingUtil.inflate(
            inflater, R.layout.layout_home, container, false
        )

        binding.btnStart.setOnClickListener {
            Snackbar.make(binding.btnStart, "This is main activity", Snackbar.LENGTH_LONG)
                .setAction("CLOSE") {
                }
                .setActionTextColor(resources.getColor(android.R.color.holo_red_light))
                .show()

        }

        return binding.root
    }
}

layout_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?android:attr/actionBarSize"
                android:background="@color/colorPrimary"
                android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar"
            />

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

        <fragment
            android:id="@+id/fragment_navigation"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            app:defaultNavHost="true"
            app:navGraph="@navigation/nav_graph" />


    </androidx.coordinatorlayout.widget.CoordinatorLayout>

</layout>

layout_home.xml

<layout 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">

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btnStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Start"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

</layout>

Image A

enter image description here


Solution

  • I don't feel like that CoordinatorLayout releases some space to let Snackbar come up. A Snackbar is just created and then attached to your given parent ViewGroup.
    You should try adding an anchor to your Snackbar to show the Snackbar above the button.

    The Snackbar has setAnchorView method to achieve this.

    setAnchorView(View anchorView)
    

    Sets the view the BaseTransientBottomBar should be anchored above.

    You can show a Snackbar above your button by giving Button's View Id like below:
    Snackbar.make(binding.btnStart, "This is main activity", Snackbar.LENGTH_LONG)
                    .setAction("CLOSE"){}
                    .setAnchorView(binding.btnStart.id)
                    .show()
    

    You can also try adding margin like below:

    Snackbar snack = Snackbar.make(findViewById(R.id.coordinatorLayout), 
        "Your message", Snackbar.LENGTH_LONG);
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) 
        snack.getView().getLayoutParams();
    params.setMargins(leftMargin, topMargin, rightMargin, bottomBar.height);
    snack.getView().setLayoutParams(params);
    snack.show();