最近做了一款情侣短信小软件,感兴趣的朋友可以下载安装玩玩
那接下来的事就是总结了,把几个重要的知识点总结发到博客上,以供日后参考。有兴趣的朋友也可以看看,迫切希望各位朋友能多多指教!
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 AnimationDrawable frameAnimation = null;
Context mContext = null;
/* 定义一个Drawable对象 */
Drawable mBitAnimation = 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;
}
}}
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);
}
}
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;
}
}
}