zoukankan      html  css  js  c++  java
  • 仿腾讯手机管家火箭发射

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

        实现步骤: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的一些參数的熟悉。
             
    作者能力有限,特别是设计模式方面 不是非常懂,希望高手多多指点



             


  • 相关阅读:
    10.20stark组件已经完工
    webpack3到webpack4
    app埋点
    postman使用
    phantomjs
    nodejieba中文分词
    爬虫--cheerio
    mysql命令(三)
    mysql学习(二)
    mysql安装登录
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7149081.html
Copyright © 2011-2022 走看看