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
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)
You can show a Snackbar above your button by giving Button's View Id like below:Sets the view the BaseTransientBottomBar should be anchored above.
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();