仿腾讯手机管家火箭发射

好久没有写过博客了。前段时间一个项目中用到了浮点(漂浮在窗口上),于是突发灵感发现能够实现类似于腾讯手机管家火箭升空效果

    实现步骤:1:新建一个类 名为RocketView(用来显示浮点,当手指拖动浮点变成火箭图标)

                        2:新建一个类 名LaunchView(火箭发射台,当手指拖动RocketView浮点到指定位置释放手指后 火箭深空)

                        3:在activity中调用RocketView的显示浮点方法进行演示

                        4:总结

1:新建一个类 名为RocketView(用来显示浮点,当手指拖动浮点变成火箭图标)

package com.masa.rocketlaunch;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.TextView;

/**
 * author:janecer 
 * email:jiangxiaocai@youline.com.cn
 * 2014年10月22日  下午3:41:59
 * 类说明 
 */
public class RocketView  extends FrameLayout{

	private static final String TAG = null;
	private static final  int ROCKET_SENDING=10;
	private static final int ROCKET_SENDED=11;
	private static final int VIBRATE=12;
	private static final String FLOAT_MARK="float_mark";
	private WindowManager wm;
	private WindowManager.LayoutParams wlp;
	private TextView tv_rocket;
	private Context ctx;
	private int statusBar;//状态栏高度
	private LaunchView launchView;
	
	private float x;
	private float y;
	
	//在拖到 发射台发射之前 几下浮点的位置,以便发射完后  把浮点设置到这个位置
	private float x_o;
	private float y_o;
	
	private float xInScrren;
	private float yInScrren;
	
	private Vibrator vibrator;
	private boolean isVibrator=false;
	
	private int rocket_height;//火箭的高度
	/**
	 * 手机屏幕的宽度和高度
	 */
	private int s_width;
	private int s_height;
	
	/**
	 * 推断火箭是否在飞行中。假设在飞行中。避免手指再次出破屏幕
	 */
	private boolean isFlying=false;
	
	//发射火箭 
	private Handler handler=new Handler(){
		public void handleMessage(android.os.Message msg) {
		     switch (msg.what) {
			    case ROCKET_SENDING://发射火箭
				     updatePosition();
	       			break;
			    case ROCKET_SENDED://火箭发射完毕
			    	launchView.removeView();
			    	launchView.setBackgroundResource(R.drawable.rocket_base);
			    	isFlying=false;
			    	setImage(false, false);
			    	xInScrren=x_o;
			    	yInScrren=y_o;
			    	
			    	updatePosition();
			    	break;
			    case VIBRATE:
			    	vibrator.vibrate(msg.arg1);
			    	break;
			} 	
		};
	};
	
	public RocketView(Context context) {
		this(context, null);
	}
	
	public RocketView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}
	
	public RocketView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		
		this.ctx=context;
		
		//初始化屏幕的宽度和高度
		this.s_height=DimensionUtil.getHeight(context);
		this.s_width=DimensionUtil.getWidth(context);
		
		//给本布局设置 长度和高度
		ViewGroup.LayoutParams vlp=new ViewGroup.LayoutParams(-2,-2);
		this.setLayoutParams(vlp);
		this.setBackgroundColor(Color.TRANSPARENT);
		
		//初始化状态栏高度
		if(context instanceof Activity){
			initStatusBar((Activity)context);
		}
		vibrator=(Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
		wm=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		wlp=new WindowManager.LayoutParams();
		
		
		//给显示浮点的ImaView初始化 
		tv_rocket=new TextView(context);
		tv_rocket.setGravity(Gravity.CENTER);
		FrameLayout.LayoutParams flp=new FrameLayout.LayoutParams(-2,-2);
		tv_rocket.setLayoutParams(flp);
		
		
		setImage(false,false);
        this.addView(tv_rocket);
        Log.i(TAG, "RocketView:___>");
	}
	
	/**
	 * 设置发射台的window
	 * @param lv
	 */
	public void setLaunchView(LaunchView lv){
		this.launchView=lv;
	}
	/**
	 * 用来设置 图标是火箭图标 还是 圆形图标
	 * @param isRocket   
	 * @param isRelease  true表示 正在深空的火箭  
	 */
	public void setImage(boolean isRocket,boolean isRelease){
		if(isRocket){
			tv_rocket.setText("");
			tv_rocket.setBackgroundResource(isRelease?

R.drawable.rocket_release:R.drawable.rocket_unrelease); }else{ //设置圆形图标 tv_rocket.setBackgroundResource(R.drawable.float_); tv_rocket.setText(((Util.getUsefoMe(ctx)*100)/Util.getTotalMe())+"%"); } // wlp.width = -2; // wlp.height =-2; // wm.updateViewLayout(this, wlp); } public void addToWindow(){ wlp.width = -2; wlp.height = -2; wlp.format=PixelFormat.RGBA_8888; wlp.type=WindowManager.LayoutParams.TYPE_PHONE; wlp.flags=WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; wlp.gravity=Gravity.LEFT|Gravity.TOP; wlp.x=DimensionUtil.getWidth(ctx)/2; wlp.y=(DimensionUtil.getHeight(ctx)-statusBar)/2; // wlp.alpha=0.5f; wm.addView(this,wlp); } public void removeViewFromWindow(){ wm.removeView(this); } @Override public boolean onTouchEvent(MotionEvent ev) { if(!isFlying){ switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: x_o=ev.getRawX(); y_o=ev.getRawY(); this.x=ev.getX(); this.y=ev.getY(); setImage(true,false); launchView.addToWindow(); break; case MotionEvent.ACTION_MOVE: this.xInScrren= ev.getRawX(); this.yInScrren= ev.getRawY(); updatePosition(); //Log.i(TAG,"this.x:"+this.x+" this.y:"+this.y); if(xInScrren>launchView.x-launchView.r&&xInScrren<launchView.x+launchView.r&&yInScrren>launchView.y-launchView.r&&yInScrren<launchView.y+launchView.r){ //显示须要发射的火焰 Log.i(TAG, "显示发射火焰"); launchView.isShowFire(true); isVibrator=true; new Thread(){ public void run() { while (isVibrator) { Message msg=Message.obtain(); msg.arg1=(int) Math.round(Math.random() * 100+200); msg.what=VIBRATE; handler.sendMessage(msg); try { Thread.currentThread().sleep(msg.arg1); } catch (InterruptedException e) { e.printStackTrace(); } } }; }.start(); }else{ vibrator.cancel(); isVibrator=false; launchView.isShowFire(false); } break; case MotionEvent.ACTION_UP: isVibrator=false; //依据火焰是否显示 决定是否发射火箭 if(launchView.ivfire.getVisibility()==View.VISIBLE){ //发射火箭 Log.i(TAG, "发射火箭逻辑"); launchView.ivfire.setVisibility(View.GONE); launchView.setBackgroundResource(R.drawable.smoke_m); setImage(true,true); isFlying=true; new Thread(){ public void run() { int height=tv_rocket.getHeight(); Log.i(TAG, "火箭的高度:"+height); while (yInScrren>0) { handler.sendEmptyMessage(ROCKET_SENDING); try { Thread.currentThread().sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } yInScrren-=2; } handler.sendEmptyMessage(ROCKET_SENDED); }; }.start(); }else{ setImage(false,true); if(!isFlying){ launchView.removeView(); } } break; }} return super.onTouchEvent(ev); } public void updatePosition(){ wlp.x=(int) (this.xInScrren-this.x); wlp.y=(int) (this.yInScrren-this.y-statusBar); wm.updateViewLayout(this,wlp); } /** * 初始化状态栏高度 * @param act */ public void initStatusBar(Activity act){ if(act.getWindow().getAttributes().flags==WindowManager.LayoutParams.FLAG_FULLSCREEN){ statusBar=0; }else{ try { Class<?> clazz=Class.forName("com.android.internal.R$dimen"); Object obj=clazz.newInstance(); int j = Integer.parseInt(clazz.getField("status_bar_height").get(obj).toString()); statusBar = act.getResources().getDimensionPixelSize(j); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NumberFormatException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchFieldException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }



2:新建一个类 名LaunchView(火箭发射台。当手指拖动RocketView浮点到指定位置释放手指后 火箭深空)

package com.masa.rocketlaunch;

import java.text.Format;

import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.RelativeLayout;

/**
 * author:janecer 
 * email:jiangxiaocai@youline.com.cn
 * 2014年10月23日  下午2:08:55
 * 类说明   火箭发射台
 */
public class LaunchView extends RelativeLayout{

	
	private static final String TAG = LaunchView.class.getSimpleName();
	private WindowManager wm;
	private WindowManager.LayoutParams wlp;
	
	private Context ctx;
	
	public int x;//发射台的x坐标
	public int y;//发射台的y坐标
	public int r;//待中心点的半径
	
	
	private Handler handler=new Handler(){
		public void handleMessage(android.os.Message msg) {
		    
		 	
		};
	};
	public ImageView ivfire;
	
	
	public LaunchView(Context context) {
		this(context, null);
	}
	
	public LaunchView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}
	
	
	public LaunchView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		ctx=context;
		
		wm=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		wlp=new WindowManager.LayoutParams();
		
		
		
		ViewGroup.LayoutParams vlp=new ViewGroup.LayoutParams(-1,DimensionUtil.dip2px(context, 108));
		this.setLayoutParams(vlp);
		this.setBackgroundResource(R.drawable.rocket_base);
		
		ivfire = new ImageView(context);
		ivfire.setScaleType(ScaleType.FIT_XY);
		setImageFire();
		RelativeLayout.LayoutParams rlp=new RelativeLayout.LayoutParams((int) (DimensionUtil.getWidth(context)/4.5)*2,(int) (DimensionUtil.getWidth(context)/4.5));
		rlp.addRule(CENTER_IN_PARENT);
		this.addView(ivfire, rlp);
		
		r=(int) (DimensionUtil.getWidth(context)/4.5);
		x=DimensionUtil.getWidth(context)/2;
		y=DimensionUtil.getHeight(context)-r;
		Log.i(TAG, "x:"+x+"   y:"+y+"   r:"+r);
	}
	
	public void setImageFire( ){
		ivfire.setBackgroundResource(R.drawable.rocket_fire1);
	}
	
	public void isShowFire(boolean isshow){
		ivfire.setVisibility(isshow?

View.VISIBLE:View.GONE); } public void addToWindow(){ wlp.flags=WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; wlp.type=WindowManager.LayoutParams.TYPE_PHONE; wlp.gravity=Gravity.LEFT|Gravity.TOP; wlp.format=PixelFormat.RGBA_8888; wlp.width=this.getLayoutParams().width; wlp.height=this.getLayoutParams().height; wlp.x=0; wlp.y=DimensionUtil.getHeight(ctx); wm.addView(this,wlp); } public void removeView(){ wm.removeView(this); } }



3:在activity中调用RocketView的显示浮点方法进行演示


	    RocketView rocketView=new RocketView(this.getApplicationContext());
	    rocketView.setLaunchView(new LaunchView(this.getApplicationContext()));
	    rocketView.addToWindow();

4:总结

         浮点的实现主要使用到android api的WindowManager。以及对WIndowManager.LayoutParams的一些參数的熟悉。
         
作者能力有限,特别是设计模式方面 不是非常懂,希望高手多多指点



         


原文地址:https://www.cnblogs.com/yfceshi/p/7149081.html