如何在 Android Kotlin 中创建 BottomSheet

Posted

技术标签:

【中文标题】如何在 Android Kotlin 中创建 BottomSheet【英文标题】:How to create BottomSheet in Android Kotlin 【发布时间】:2021-04-20 14:22:04 【问题描述】:

我正在尝试在 Kotlin 中获取 Persistent BottomSheet。我总是收到错误消息: 该视图不是 CoordinatorLayout 的子视图

我的 Gradle 文件:

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'

我的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_
    android:layout_
    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_
        android:layout_
        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_
    android:layout_
    android:orientation="vertical"
    android:id="@+id/test">

    <TextView
        android:layout_
        android:layout_
        android:textSize="21sp"
        android:text="place:"
        android:id="@+id/place"
        ></TextView>

    <TextView
        android:layout_
        android:layout_
        android:textSize="21sp"
        android:text="number:"
        android:id="@+id/number"
        ></TextView>

    <Button
        android:layout_
        android:layout_
        android:text="get"
        android:id="@+id/get" />
</LinearLayout> 

还有我的 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
            
        
    

你知道为什么我总是收到错误吗? 我认为视图是 CoordinatorLayout 的子视图

感谢您的帮助 费迪

【问题讨论】:

“CoordinatorLayout 的子级”表示它实际上嵌套在 CoordinatorLayout 中,只有将其放入 activity_main 布局文件或手动将其添加到 CoordinatorLayout 时才会如此。你已经膨胀了它,但你还没有把它放在你的 CoordinatorLayout 中。 【参考方案1】:

您作为bottomSheet 使用的视图必须位于托管bottomSheet 的CoordinatorLayout 内。

因此,与其将 layout_bottom_sheet.xml 膨胀到视图中,不如将其作为 CoordinatorLayout 的子项包含在 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_
    android:layout_
    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_
        android:layout_
        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>

然后在您的 MainActivity 中,您可以简单地通过 id 获取 bottomSheet 视图并执行以下操作:

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

这应该可行。

但是,如果由于某种原因您不想直接通过 XML 添加视图,您可以像之前那样对视图进行膨胀,然后以编程方式添加它。

【讨论】:

【参考方案2】:

首先,只需从CoordinatorLayout 中删除 layout_behavior 属性。 然后在您的Activity 中调用底部表格,如下所示:

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

我对此进行了测试,它会起作用

【讨论】:

以上是关于如何在 Android Kotlin 中创建 BottomSheet的主要内容,如果未能解决你的问题,请参考以下文章

如何隐藏默认片段 actionBar 在 android & kotlin 中创建我们自己的 actionBar

如何在图标启动器 kotlin 中创建徽章编号

有没有一种方便的方法可以使用 Kotlin 在 Android 中创建 Parcelable 数据类?

如何在 Android 11 中创建从图库中选择图像的意图?

开发环境Android 命令行中执行 Java 程序 ( IntelliJ IDEA 中创建 Java / Kotlin 工程 | dx 打包 DEX 字节码文件 | dalvikvm 命令 )(代码

如何在 Kotlin 常用代码中创建动态代理?