最近做了一款情侣短信小软件,感兴趣的朋友可以下载安装玩玩

那接下来的事就是总结了,把几个重要的知识点总结发到博客上,以供日后参考。有兴趣的朋友也可以看看,迫切希望各位朋友能多多指教!

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;
    	}
    }
}