安卓的悬浮框,悬浮框相当于对桌面的一种控制,在安卓中是允许这样的自定义的小窗体出现在桌面的,其实这种小桌面可以使某些应用调用起来非常的方便,而动画的展现使得程序看起来更加有爱。

Kotlin 开发Android app(二十):悬浮框WindowManager和动画AnimationDrawable-LMLPHP

悬浮框

悬浮框的使用,通常是跟服务(Service)一起使用的,建立一个Service把窗体加载到Service中,在Service 中控制 窗体的行为。

要使用 悬浮框,需要用到的权限如下:

    <!-- 显示系统窗口权限 -->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <!-- 在 屏幕最顶部显示addview-->
    <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />

还要在权限页面中开启,不然会报如下的错误:

permission denied for window type 2038

Kotlin 开发Android app(二十):悬浮框WindowManager和动画AnimationDrawable-LMLPHP

创建一个xml页面,在Service中加载这个页面。

<?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">

    <ImageView
        android:id ="@+id/rocket_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/rocket_anim_list"/>

</LinearLayout>

Service中把页面加载到mToastRocketView 中:

mToastRocketView = View.inflate(this,R.layout.toast_rocket_view,null)

获取到悬浮窗控件:

mWindowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager?

并把mToastRocketView 放到悬浮框上。

mWindowManager!!.addView(mToastRocketView,mParams)

动画

让火箭动起来,准备两种不同动作的火箭状态,编写一段动画代码,这里的动画也是在xml中实现的。

    <!--火箭火焰喷射的动画集-->
    <item android:drawable="@drawable/rocket_launch_1" android:duration="200" />
    <item android:drawable="@drawable/rocket_launch_2" android:duration="200" />

启动动画:

        mRocketImage = mToastRocketView!!.findViewById(R.id.rocket_image) as ImageView
        var animDraw:AnimationDrawable = mRocketImage!!.background as AnimationDrawable

        animDraw.start()

Kotlin 开发Android app(二十):悬浮框WindowManager和动画AnimationDrawable-LMLPHP

让火箭跟随我们的拖动而动起来,要相应mToastRocketView 的接触事件setOnTouchListener,当按下MotionEvent.ACTION_DOWN,拖动MotionEvent.ACTION_MOVE和放开MotionEvent.ACTION_UP,响应不同的逻辑处理。在拖动时,根据位置进行调整updateViewLayout ,当放开时,发射火箭。

    private fun launchRocket(){
        Thread {
            var disY = mWindowManager!!.defaultDisplay.height /5
            for(i in 0..6){
                var height =  mWindowManager!!.defaultDisplay.height - i*disY

                Thread.sleep(50)

                var msg:Message = Message()
                msg.obj = height
                mHandler.sendMessage(msg)

            }

        }.start()
    }

更新火箭的位置

    var mHandler:LaunchHandler = LaunchHandler()
    inner class LaunchHandler:Handler(){
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            mParams!!.y = msg.obj as Int
            mWindowManager!!.updateViewLayout(mToastRocketView,mParams)

        }
    }

Kotlin 开发Android app(二十):悬浮框WindowManager和动画AnimationDrawable-LMLPHP

小结

这一节中,介绍了是悬浮框WindowManager,悬浮框中在服务中,并在悬浮窗中关联到界面,这是我们经常用到的,也是服务的一个用法。

12-08 21:41