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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:46:25