效果图 :

这种效果类似腾讯安全卫士的小火箭.. ps:图也是在那里盗的= ,=
小火箭 是常驻在后台的. 所以我们在服务里面写逻辑,
要实现这种效果. 我们要知道火箭 是悬浮在窗体上的. 这时我们需要WindowManager服务的addView 来实现
需注意 弹出窗体 需要系统权限.
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
下面贴代码 主Activity : 用于开启 服务 和关闭服务
public class RocketFly extends Activity {
Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rocket_fly);
// open rocket service
intent = new Intent(this, RocketService.class);
startService(intent);
// finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
stopService(intent);
}
}
下面是服务内 代码:
@Override
public void onCreate() {
super.onCreate();
mWM = (WindowManager) getSystemService(WINDOW_SERVICE);
iv = new ImageView(getApplicationContext());
iv.setBackgroundResource(R.drawable.rocket_list);
AnimationDrawable ad = (AnimationDrawable) iv.getBackground();
ad.start();
params = mParams;
// window manager 坐标系和普通的不同. 它是以自己view 的左上角为0进行计算
// ,为了方便坐标计算. 我们把它对齐方式设置在左上角
params.gravity = Gravity.LEFT + Gravity.TOP;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
// get the screen width and height
DisplayMetrics displayMetrics = new DisplayMetrics();
mWM.getDefaultDisplay().getMetrics(displayMetrics);
// default display position
// should be judge whether the first to enter
screenWidth = displayMetrics.widthPixels ;
screenHeight = displayMetrics.heightPixels ;
params.x = screenWidth /2;
params.y = screenHeight /2;
params.format = PixelFormat.TRANSLUCENT ; // 窗体透明
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
params.setTitle("Toast");
// TYPE_PRIORITY_PHONE 可以被触摸 需权限. Type_Toast 天生不可以被触摸
params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
mWM.addView(iv, mParams);
// 相应 rocket 滑动
setTouchEvent(iv, params);
上面代码所需要注意的是: 我们需要设置这种 可以被触摸的类型
params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
在源码中 params.type的类型是 , 这种类型 天生不可以被触摸.
params.type = WindowManager.LayoutParams.Toast;
还需要注意 对齐方式. 与屏幕左上角对齐
params.gravity = Gravity.LEFT + Gravity.TOP;
上面的代码写完. 一个小火箭就会显示在屏幕中间了
下面我们贴手指触摸移动的代码:
<strong> </strong> private void setTouchEvent(final ImageView iv, final WindowManager.LayoutParams params) {
if (iv != null) {
iv.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = (int) event.getRawX();
startY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int lastX = (int) event.getRawX();
int lastY = (int) event.getRawY();
int dx = lastX - startX;
int dy = lastY - startY;
params.x += dx;
params.y += dy;
<span style="white-space:pre"> </span> //如果小火箭 在最左面 不让它在往左滑动了
if (params.x < 0) {
params.x = 0;
}
<span style="white-space:pre"> </span> //同上
if (params.x > screenWidth - iv.getWidth()) {
params.x = screenWidth - iv.getWidth();
}
<span style="white-space:pre"> </span> //....
if (params.y < 0) {
params.y = 0;
}
<span style="white-space:pre"> </span> //....
if (params.y > screenHeight - iv.getHeight()) {
params.y = screenHeight - iv.getHeight();
}
// 更新 window manager
mWM.updateViewLayout(iv, params);
<span style="white-space:pre"> </span> // 记录上次的点.
startX = lastX;
startY = lastY;
break;
case MotionEvent.ACTION_UP:
int upX = (int) event.getRawX();
int upY = (int) event.getRawY();
//满足条件 发射小火箭
if (upX > screenWidth /2 - iv.getWidth() / 2 && upX < screenWidth /2 + iv.getWidth() && upY > 600) {
Intent intent = new Intent(RocketService.this, Smoke.class);
// 在服务里开启activity 需要 设置标记
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
new Thread() {
@Override
public void run() {
for (int i = 0; i < 360; i++) { //这里的360是随便写的. 只要能到顶部就可以
handler.sendEmptyMessage(0);
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
break;
}
return true;
}
});
}
}
烟雾效果的Activity代码:
public class Smoke extends Activity {
private ImageView smoke1;
private ImageView smoke2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_smoke);
smoke1 = (ImageView) findViewById(R.id.smoke1); // 下方大烟雾
smoke2 = (ImageView) findViewById(R.id.smoke2); // 小烟雾
AlphaAnimation aa = new AlphaAnimation(0.0f, 1.0f);
aa.setFillAfter(true);
aa.setDuration(500);
smoke1.setAnimation(aa);
aa.setDuration(700);
smoke2.startAnimation(aa);
new Thread(){
@Override
public void run() {
try {
Thread.sleep(2000);
runOnUiThread(new Runnable() {
@Override
public void run() {
finish(); // 过两秒 让烟雾消失.
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
}
布局文件就是几个ImageView 这里就不贴了.
还有必须要设置Activity 为透明的. 需要在AndroidManifest.xml 中添加 主题
<activity
android:name=".RocketFly"
android:label="@string/title_activity_rocket_fly"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
以上就是 实现小火箭喷烟雾的效果了.. 有些细节没有处理.. 因为都比较好实现了嘛..
写的不好望见谅 = ,=