好久没有写过博客了,前段时间一个项目中用到了浮点(漂浮在窗体上),于是突发灵感发现可以实现类似于腾讯手机管家火箭升空效果
实现步骤: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:[email protected] * 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:[email protected] * 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的一些参数的熟悉。
作者能力有限,特别是设计模式方面 不是很懂,希望高手多多指点
时间: 2024-10-03 08:07:53