LoginSignup
0
0

More than 3 years have passed since last update.

【Kotlin】スクロールと連動させつつ動的にFABを表示したり隠したりする

Posted at

はじめに

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とは共存できないっぽく、今のところこれが一番楽でいい感じかなーと思いました。
なにかおかしなことしてたら教えて頂けると嬉しいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0