You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建如附件所示且具备默认、拖动、关闭分阶段交互效果的BottomSheetDialogFragment

Got it, let's build that BottomSheetDialogFragment that behaves exactly like your sample—with clear default, dragged, and closed states. Here's a step-by-step implementation tailored to your needs:

Step 1: Create the Bottom Sheet Layout

First, define the layout for your bottom sheet (res/layout/bottom_sheet_content.xml). Adjust the content to match your sample's UI:

<?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="wrap_content"
    android:orientation="vertical"
    android:padding="16dp"
    android:background="@drawable/bottom_sheet_rounded_bg">

    <!-- Add your sample UI elements here (title, buttons, etc.) -->
    <TextView
        android:id="@+id/state_indicator"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Default State"
        android:textSize="18sp"
        android:textStyle="bold"/>

    <!-- Add more content as needed -->

</LinearLayout>

Note: Create a bottom_sheet_rounded_bg.xml drawable for rounded top corners to match typical bottom sheet styling.

Step 2: Implement the BottomSheetDialogFragment Subclass

Create a subclass of BottomSheetDialogFragment and wire up state handling using BottomSheetBehavior to control and listen to state changes:

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment

class CustomBottomSheetDialog : BottomSheetDialogFragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.bottom_sheet_content, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        // Get the core bottom sheet view and its behavior
        val bottomSheet = dialog?.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
        val behavior = BottomSheetBehavior.from(bottomSheet!!)
        
        // Configure default state: set peek height (visible portion when collapsed)
        behavior.peekHeight = 300 // Adjust this value to match your sample's default visible height
        behavior.isHideable = true // Enable dragging to close
        
        // Listen for state transitions
        behavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
            override fun onStateChanged(bottomSheet: View, newState: Int) {
                val stateText = view.findViewById<TextView>(R.id.state_indicator)
                when(newState) {
                    BottomSheetBehavior.STATE_COLLAPSED -> {
                        // Default state: reset UI to initial state
                        stateText.text = "Default State"
                    }
                    BottomSheetBehavior.STATE_DRAGGING -> {
                        // Dragging state: update UI to show active interaction
                        stateText.text = "Dragging State"
                    }
                    BottomSheetBehavior.STATE_HIDDEN -> {
                        // Closed state: dismiss the dialog completely
                        dismiss()
                    }
                    // Optional: Handle expanded state if your sample uses it
                    BottomSheetBehavior.STATE_EXPANDED -> {
                        stateText.text = "Expanded State"
                    }
                }
            }

            override fun onSlide(bottomSheet: View, slideOffset: Float) {
                // Add smooth UI transitions during dragging (e.g., opacity, scaling)
                // Example: Fade out as user drags toward closing
                if (slideOffset < 0) {
                    bottomSheet.alpha = 1 + slideOffset
                }
            }
        })
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        // Apply custom theme to match sample styling
        val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
        dialog.context.setTheme(R.style.CustomBottomSheetDialogTheme)
        return dialog
    }
}

Add a custom theme to styles.xml to match your sample's visual style:

<style name="CustomBottomSheetDialogTheme" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/CustomBottomSheetStyle</item>
    <item name="android:windowIsFloating">false</item>
</style>

<style name="CustomBottomSheetStyle" parent="Widget.MaterialComponents.BottomSheet.Modal">
    <item name="android:background">@drawable/bottom_sheet_rounded_bg</item>
    <item name="behavior_peekHeight">300dp</item>
    <item name="behavior_hideable">true</item>
</style>
Step 4: Show the Bottom Sheet

To display your bottom sheet from an Activity or Fragment:

val bottomSheet = CustomBottomSheetDialog()
bottomSheet.show(supportFragmentManager, "CustomBottomSheet")

Key Notes:

  • Adjust peekHeight to match your sample's default visible height (convert dp to pixels programmatically if you need dynamic sizing).
  • Modify the onSlide callback to add any visual transitions (like scaling, fading) that match your sample's dragged state behavior.
  • If your sample requires a custom drag threshold for closing, extend BottomSheetBehavior to override the hide trigger logic.

内容的提问来源于stack exchange,提问作者Chirag Thummar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 19:52:33