はじめに
FloatingActionButtonを使うときはCoordinatorLayoutやRecyclerViewと一緒に使ったりして、スクロールに合わせて表示・非表示を切り替えるかと思います。
この場合は、レイアウトファイルのFABに「app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"」と書けばスクロールにあわせていい感じにやってくれます。
しかし、これだと何らかの理由でスクロールができなくなった時にFABが隠れたままになってしまうことがあります。
どうするか
HideBottomViewOnScrollBehaviorにはslideUp/slideDownメソッドがあるのですが、protectedなメソッドのため外部から呼ぶことはできません。
なので継承したクラスでオーバーライドします。
ListActivity.kt
class ListActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_list)
fab = findViewById<FloatingActionButton>(R.id.fab)
}
class FabScrollBehavior<V:View>(context: Context?, attrs:AttributeSet?):HideBottomViewOnScrollBehavior<V>(context,attrs){
public override fun slideDown(child: V) {
super.slideDown(child)
}
public override fun slideUp(child: V) {
super.slideUp(child)
}
}
}
それと、app:layout_behaviorも自作したクラスに変更します。
activity_list.xml
<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="com.test.ListActivity">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:layout_behavior="com.test.ListActivity$FabScrollBehavior"<!--自作したクラスにする--
android:layout_gravity="bottom|end"
android:layout_marginBottom="15sp"
android:layout_marginEnd="15sp"
android:src="@android:drawable/ic_input_add"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
あとは好きな時にslideUpやslideDownを呼ぶだけです。
ListActivity.kt
class ListActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_list)
fab = findViewById<FloatingActionButton>(R.id.fab)
}
private fun showFab(){//FABを表示する
val behavior = (fab.layoutParams as? CoordinatorLayout.LayoutParams)?.behavior as? FabScrollBehavior?: return
behavior.slideUp(fab)
}
class FabScrollBehavior<V:View>(context: Context?, attrs:AttributeSet?):HideBottomViewOnScrollBehavior<V>(context,attrs){
public override fun slideDown(child: V) {
super.slideDown(child)
}
public override fun slideUp(child: V) {
super.slideUp(child)
}
}
}
おしまい
FABにはhide()やshow()メソッドがあっても、HideBottomViewOnScrollBehaviorとは共存できないっぽく、今のところこれが一番楽でいい感じかなーと思いました。
なにかおかしなことしてたら教えて頂けると嬉しいです。