Ferdi
Ferdi

Reputation: 11

How to create BottomSheet in Android Kotlin

I'm trying to get a Persistent BottomSheet in Kotlin. I always get the error message: The view is not a child of CoordinatorLayout

My Gradle File:

dependencies {

    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    implementation 'androidx.navigation:navigation-fragment-ktx:2.3.2'
    implementation 'androidx.navigation:navigation-ui-ktx:2.3.2'
    implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"

    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

My activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".MainActivity"
    app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
    >

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/floatingActionButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp"
        android:clickable="true"
        android:focusable="true"
        android:src="@drawable/add"
        app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />


</androidx.coordinatorlayout.widget.CoordinatorLayout>

layout_bottom_sheet.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/test">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="21sp"
        android:text="place:"
        android:id="@+id/place"
        ></TextView>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="21sp"
        android:text="number:"
        android:id="@+id/number"
        ></TextView>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="get"
        android:id="@+id/get" />
</LinearLayout> 

And my MainAcitvity.kt:


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val bottomView = layoutInflater.inflate(R.layout.layout_bottom_sheet, null)
        val bottomSheetBehavior: BottomSheetBehavior<*> = BottomSheetBehavior.from<View>(bottomView)

        val fab: FloatingActionButton = findViewById(R.id.floatingActionButton)
        fab.setOnClickListener {
            if (bottomSheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED) {
                bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
            } else {
                bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
            }
        }
    }
}

Do you know why I always get the error? I think the view is a child of the CoordinatorLayout

Thanks for your help Ferdi

Upvotes: 1

Views: 3607

Answers (2)

Masoud Badrmiran
Masoud Badrmiran

Reputation: 451

First, just remove layout_behavior attribute from CoordinatorLayout. Then in your Activity call the bottom sheet like below:

    val btnsheet = layoutInflater.inflate(R.layout.layout_bottom_sheet, null)
    val dialog = BottomSheetDialog(this)
    dialog.setContentView(btnsheet)
    dialog.show()

I tested this and it will work

Upvotes: 2

El Nuru
El Nuru

Reputation: 106

The View You are usings as your bottomSheet has to be inside the CoordinatorLayout hosting the bottomSheet.

So Instead of inflating the layout_bottom_sheet.xml into a View, you should just include it inside activity_main.xml as a child of the CoordinatorLayout:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".MainActivity"
    app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
    >

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/floatingActionButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp"
        android:clickable="true"
        android:focusable="true"
        android:src="@drawable/add"
        app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />

     <include
         android:id="@+id/bottom_sheet_view"
         layout="@layout/layout_bottom_sheet.xml"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Then in your MainActivity,you can simply get the bottomSheet view by id and do:

  val bottomView = findViewById<View>(R.id.bottom_sheet_view)
  val bottomSheetBehavior: BottomSheetBehavior<*> = BottomSheetBehavior.from<View>(bottomView)

And that should work.

But if for some reason you don't want to add the view directly via XML, you can inflate the view as you have done then add it programmatically.

Upvotes: 0

Related Questions