Android情侣短信软件(1)--Frame动画在悬浮窗口上的实现
16lz
2021-01-26
最近做了一款情侣短信小软件,感兴趣的朋友可以下载安装玩玩,链接地址 LoveSms.apk
那接下来的事就是总结了,把几个重要的知识点总结发到博客上,以供日后参考。有兴趣的朋友也可以看看,迫切希望各位朋友能多多指教!
Android情侣短信软件(1)--Frame动画在悬浮窗口上的实现
效果图如下:
(注:图中阿狸是动画的)
(1)悬浮窗口实现起来很简单,就是在WindowManager中添加View就即可,
WindowManager最常用的方法有3个:
<1> public abstract void addView(View view, ViewGroup.LayoutParams params) 添加View<2> public abstract void removeView(View view) 移除View<3> public abstract void updateViewLayout(View view, ViewGroup.LayoutParams params) 更改View在屏幕中的位置
然后通过WindowManager.LayoutParams可以设置悬浮窗口的属性,比如大小,在屏幕中的位置等等。
当然要在AndroidManifest.xml添加权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
(2)Frame动画一点要说明,要让它start,要有一个事件去驱动它,比如说点击一个按钮!
这里我们为了让它自动播放,我们把frameAnimation.start();放入OnPreDrawListener(){}这个监听器中去触发它,触发流程图及原理如下:
然后将Frame动画看成一个View添加到WindowManager即可!
各个类结构结构如下:
最后实现的效果:按HOME键或返回键,退出主界面时,显示悬浮动画,可用手指滑动悬浮动画,当手指抬起时,动画消失,返回主界面! 不对的地方还望朋友们纠正!
本文工程代码:点击打开链接
闲话少说,贴代码:
Myfloatview.Java
package com.myFloatWindow;import java.util.Timer;import java.util.TimerTask;import android.content.Context;import android.content.Intent;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.drawable.AnimationDrawable;import android.graphics.drawable.Drawable;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.view.KeyEvent;import android.view.MotionEvent;import android.view.View;import android.view.WindowManager;import android.view.ViewTreeObserver.OnPreDrawListener;import android.widget.Button;public class myfloatview extends View{private float mTouchStartX; private float mTouchStartY; private float x; private float y;static AnimationDrawableframeAnimation= null;ContextmContext= null;/* 定义一个Drawable对象 */DrawablemBitAnimation= null;WindowManager wm=(WindowManager)getContext().getApplicationContext().getSystemService("window"); WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams(); static OnPreDrawListener opdl;public myfloatview(Context context){super(context);mContext = context;/* 实例化AnimationDrawable对象 */frameAnimation = new AnimationDrawable();/* 装载资源 *///这里用一个循环了装载所有名字类似的资源//如“a1.......15.png”的图片//这个方法用处非常大for (int i = 0; i <4; i++){int id = getResources().getIdentifier("a"+ i, "drawable", mContext.getPackageName());mBitAnimation = getResources().getDrawable(id);/* 为动画添加一帧 *///参数mBitAnimation是该帧的图片//参数100是该帧显示的时间,按毫秒计算frameAnimation.addFrame(mBitAnimation, 100);}frameAnimation.setOneShot( false ); /* 设置播放模式是否循环false表示循环而true表示不循环 */this.setBackgroundDrawable(frameAnimation);opdl=new OnPreDrawListener(){ @Override public boolean onPreDraw() { frameAnimation.start(); return true; } }; this.getViewTreeObserver().addOnPreDrawListener(opdl);}public void onDraw(Canvas canvas){super.onDraw(canvas);} public boolean onTouchEvent(MotionEvent event) { //获取相对屏幕的坐标,即以屏幕左上角为原点 x = event.getRawX(); y = event.getRawY()-25; //25是系统状态栏的高度 switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //获取相对View的坐标,即以此View左上角为原点 mTouchStartX = event.getX(); mTouchStartY = event.getY(); break; case MotionEvent.ACTION_MOVE: updateViewPosition(); break; case MotionEvent.ACTION_UP: updateViewPosition(); mTouchStartX=mTouchStartY=0; Intent i=new Intent(mContext,MyFloatWindowActivity.class); //当手指抬起时,返回主界面 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(i); break; } return true; } private void updateViewPosition(){ //更新浮动窗口位置参数 wmParams.x=(int)( x-mTouchStartX-136); wmParams.y=(int) (y-mTouchStartY-136); wmParams.width=136; wmParams.height= 136; wmParams.type=2002; //type是关键,这里的2002表示系统级窗口,你也可以试试2003。 wmParams.format=1; wmParams.flags=40; wm.updateViewLayout(this, wmParams); }}
createWindow.java
package com.myFloatWindow;import android.app.Activity;import android.content.Context;import android.view.Gravity;import android.view.WindowManager;import android.widget.Button;public class createWindow { static WindowManager wm;WindowManager.LayoutParams wmParams=null;static myfloatview mv;public createWindow(Context context,Boolean flag){ wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); wmParams = new WindowManager.LayoutParams(); wmParams.type=2002; //type是关键,这里的2002表示系统级窗口,你也可以试试2003。 wmParams.format=1; wmParams.flags=40; wmParams.gravity=Gravity.LEFT|Gravity.TOP; //调整悬浮窗口至左上角 //以屏幕左上角为原点,设置x、y初始值 // wmParams.x=0; //wmParams.y=0; wmParams.width=136; wmParams.height= 136; mv=new myfloatview(context); wm.addView(mv, wmParams); }}
MyFloatWindowActivity.java
package com.myFloatWindow;import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.view.Gravity;import android.view.WindowManager;public class MyFloatWindowActivity extends Activity { /** Called when the activity is first created. */static boolean flag1=false; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void onStop(){ super.onStop(); new createWindow(getBaseContext(),true); flag1=true; } public void onWindowFocusChanged(boolean hasFocus){ if(flag1==true){ createWindow.wm.removeView(createWindow.mv); flag1=false; } }}
更多相关文章
- Android仿“守望先锋”加载动画
- Android(安卓)Studio录制手机屏幕并制作GIF演示动画
- Android(安卓)淡入淡出动画
- Android(安卓)自定义动画 单个View平面位移以及一组View轮回旋转
- 【Android的从零单排开发日记】之入门篇(十六)——Android的动画效
- Android(安卓)UI--ViewPager扩展Tab标签指示
- [置顶] android动画详解一 概述
- 深入源码系列:聊聊android属性动画执行线程问题(invalidate(false
- Android中的动画和原理(帧动画和补间动画)