Android Studio实现点击按钮控制页面半滑显示/隐藏功能
实现可滑动的半屏悬浮面板(类似Snackbar交互)
这需求我之前帮朋友实现过,用Android原生的属性动画+Window视图嵌入就能搞定,不用额外开Activity,还能轻松展示当前Activity的信息。下面是完整的实现步骤和代码:
一、先写悬浮面板的布局(res/layout/layout_slide_panel.xml)
这个布局就是你要滑动的面板,里面可以放任何你想展示的Activity相关信息,比如当前Activity名称、包名、栈信息等等:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/slide_panel" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#CCFFFFFF" android:orientation="vertical" android:padding="16dp"> <!-- 展示Activity信息的示例控件 --> <TextView android:id="@+id/tv_activity_info" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="16sp" android:textColor="#333333"/> <!-- 可以加其他控件,比如按钮、图标等 --> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="测试按钮"/> </LinearLayout>
二、在Activity中实现滑动逻辑
核心思路是:把面板添加到当前Activity的Window根视图里,通过属性动画控制它的Y轴位移,点击按钮切换展开/收起状态。
import android.animation.ObjectAnimator import android.os.Bundle import android.util.DisplayMetrics import android.view.ViewGroup import android.widget.Button import android.widget.LinearLayout import android.widget.TextView import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity() { private lateinit var slidePanel: LinearLayout private lateinit var toggleBtn: Button private var isPanelExpanded = false // 记录面板状态:展开/收起 private var screenHeight = 0 // 屏幕高度 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) toggleBtn = findViewById(R.id.btn_toggle_panel) initSlidePanel() setupToggleListener() } private fun initSlidePanel() { // 初始化滑动面板 slidePanel = layoutInflater.inflate(R.layout.layout_slide_panel, null) as LinearLayout // 把面板添加到当前Activity的Window根视图 val rootLayout = window.decorView.findViewById<ViewGroup>(android.R.id.content).parent as ViewGroup rootLayout.addView(slidePanel) // 获取屏幕高度 val displayMetrics = DisplayMetrics() windowManager.defaultDisplay.getMetrics(displayMetrics) screenHeight = displayMetrics.heightPixels // 监听面板布局完成,设置初始状态 slidePanel.post { // 初始状态:把面板移到屏幕底部(完全隐藏) slidePanel.translationY = screenHeight.toFloat() // 填充Activity信息 updateActivityInfo() } } private fun updateActivityInfo() { // 展示当前Activity的相关信息,比如类名、包名 val activityName = this::class.java.simpleName val packageName = packageName slidePanel.findViewById<TextView>(R.id.tv_activity_info).text = "当前Activity: $activityName\n包名: $packageName" } private fun setupToggleListener() { toggleBtn.setOnClickListener { if (isPanelExpanded) { // 收起面板:滑回屏幕底部 ObjectAnimator.ofFloat(slidePanel, "translationY", screenHeight.toFloat()).apply { duration = 300 start() } } else { // 展开面板:滑到屏幕一半位置 val targetY = (screenHeight / 2).toFloat() ObjectAnimator.ofFloat(slidePanel, "translationY", targetY).apply { duration = 300 start() } } isPanelExpanded = !isPanelExpanded } } }
三、关键细节说明
- 视图嵌入方式:通过把面板添加到Activity的DecorView根布局,实现了非Activity级别的悬浮面板,完全依附当前Activity的生命周期,不会出现独立页面的跳转问题。
- 动画控制:用
ObjectAnimator做Y轴位移动画,比传统的TranslateAnimation更靠谱,因为它会真正改变View的位置属性,不会出现点击区域错位的问题。 - 状态维护:用
isPanelExpanded变量记录当前面板状态,确保点击按钮能正确切换展开/收起状态。 - 信息展示:通过
updateActivityInfo()方法可以轻松获取并展示当前Activity的任何信息,比如栈状态、Intent参数、页面耗时等等,按需修改就行。
如果想调整面板的停留位置,直接修改targetY的值就好:比如想让面板完全贴到屏幕顶部,就设为0f;想让面板底部对齐屏幕中点,就设为(screenHeight - slidePanel.height)/2.toFloat()。
内容的提问来源于stack exchange,提问作者user9408452
相关产品推荐
相关产品推荐

