功能分析: 
1、小火箭游离在activity之外,不依附于任何activity,不管activity是否开启,不影响小火箭的代码逻辑,所以小火箭的代码逻辑是要写在服务中; 
2、小火箭挂载在手机窗体之上; 
3、小火箭喷射火焰,两种图片轮流展示的动画集; 
4、小火箭可以拖拽到任意位置; 
5、小火箭拖拽到指定区域才可以触发发射效果; 
6、小火箭喷射尾气动画效果;

功能实现:

定义小火箭的服务,实现自定义Toast的创建,自定义Toast加载相应的布局文件,然后把自定义Toast挂载到手机窗体之上;

public class RocketService extends Service {

    // 手机窗体布局的管理者
private WindowManager mWindowManager;
// 手机窗体的布局
private WindowManager.LayoutParams mParams;
// 展示小火箭的自定义布局
private View mToastRocketView;
// 展示小火箭的ImageView
private ImageView mRocketImage;
// 手机窗体的宽度
private int mWindowWidth;
// 手机窗体的高度
private int mWindowHeight;
// 消息传递机制
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
mParams.y = (Integer) msg.obj;
mWindowManager.updateViewLayout(mToastRocketView, mParams);
}
}; @Override
public void onCreate() {
mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
// 获取手机屏幕的宽高值
mWindowWidth = mWindowManager.getDefaultDisplay().getWidth();
mWindowHeight = mWindowManager.getDefaultDisplay().getHeight();
mParams = new WindowManager.LayoutParams();
// 服务启动,打开自定义Toast的控件
showRocketView();
// 拖拽小火箭到任意位置
dragRocket();
super.onCreate();
} /**
* 拖拽小火箭到任意位置
*/
private void dragRocket() {
mToastRocketView.setOnTouchListener(new View.OnTouchListener() {
private int startX;
private int startY; @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 moveX = (int) event.getRawX();
int moveY = (int) event.getRawY();
// 两个方向上所移动的距离值
int disX = moveX - startX;
int disY = moveY - startY; mParams.x = mParams.x + disX;
mParams.y = mParams.y + disY; if (mParams.x < 0) {
mParams.x = 0;
} if (mParams.y < 0) {
mParams.y = 0;
} if (mParams.x > mWindowManager.getDefaultDisplay().getWidth() - v.getWidth()) {
mParams.x = mWindowManager.getDefaultDisplay().getWidth() - v.getWidth();
} if (mParams.y > mWindowManager.getDefaultDisplay().getHeight() - 21 - v.getHeight()) {
mParams.y = mWindowManager.getDefaultDisplay().getHeight() - 21 - v.getHeight();
} // 更新小火箭的坐标位置X和Y值
mWindowManager.updateViewLayout(mToastRocketView, mParams); startX = (int) event.getRawX();
startY = (int) event.getRawY(); break;
case MotionEvent.ACTION_UP:
// 小火箭拖拽到手机屏幕下方的中间时,触发小火箭发射
if (mParams.x > mWindowWidth / 2 - 150 && mParams.x < mWindowWidth / 2 - mToastRocketView.getWidth() / 2 + 50
&& mParams.y > mWindowHeight - mToastRocketView.getHeight() - 25) {
// 小火箭发射升空
launchRocket();
Intent intent = new Intent(RocketService.this, SmokeBackActivity.class);
// 服务中开启activity,需要设置任务栈
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);
}
break;
}
return false;
}
});
} /**
* 小火箭发射升空
*/
private void launchRocket() {
new Thread(new Runnable() {
@Override
public void run() {
int disY = mWindowHeight / 5;
for (int i = 0; i < 6; i++) {
int height = mWindowHeight - i * disY;
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 子线程不能改变主线程中的UI的变化,因此,由消息机制告知主线程进行改变,并携带相应的值
Message msg = Message.obtain();
msg.obj = height;
mHandler.sendMessage(msg);
}
}
}).start();
} /**
* 显示小火箭的自定义View
*/
private void showRocketView() {
// 自定义Toast
mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
// 修改完左上角对齐
mParams.gravity = Gravity.LEFT + Gravity.TOP;
mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
mParams.format = PixelFormat.TRANSLUCENT;
mParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
// 加载ToastRocketView显示效果的布局文件
mToastRocketView = View.inflate(this, R.layout.toast_rocket_view, null);
// 窗体布局中加入自定义的展示小火箭的View
mWindowManager.addView(mToastRocketView, mParams);
mRocketImage = (ImageView) mToastRocketView.findViewById(R.id.rocket_image);
// 获取动画,并开启动画
AnimationDrawable animDraw = (AnimationDrawable) mRocketImage.getBackground();
animDraw.start();
} @Override
public IBinder onBind(Intent intent) {
return null;
} @Override
public void onDestroy() {
if (mWindowManager != null && mToastRocketView != null) {
mWindowManager.removeView(mToastRocketView);
}
super.onDestroy();
}
}

mWindowManager是所有桌面悬浮窗的管理器,这里用于添加我们自定义的小火箭的Toast,然后获取小火箭火焰喷射的动画集,并开启动画效果。上述代码中为mToastRocketView添加了触摸事件,用于监听小火箭的拖拽事件,在监听拖拽事件的同时,若小火箭被拖动到指定区域,则触发小火箭的发射效果;

小火箭所在的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <!--背景为小火箭火焰喷射的动画集-->
<ImageView
android:id="@+id/rocket_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/rocket_anim_list"/> </LinearLayout>

小火箭火焰喷射的动画集:

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"> <!--小火箭火焰喷射的动画集-->
<item android:drawable="@drawable/rocket_launch_1" android:duration="200" />
<item android:drawable="@drawable/rocket_launch_2" android:duration="200" /> </animation-list>

小火箭发射时的尾气喷射动画效果,这里为了获得好的效果,需要在AndroidManifest.xml中配置活动的主题为透明、无标题和全屏;

public class SmokeBackActivity extends Activity {
// 尾气喷射上部图片所在的ImageView
private ImageView mSmokeTopImageView;
// 尾气喷射下部图片所在的ImageView
private ImageView mSmokeBottomImageView; private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// 尾气喷射动画结束后关闭活动
finish();
}
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_smoke_back);
// 初始化布局文件
initView();
} /**
* 初始化布局文件
*/
private void initView() {
mSmokeTopImageView = (ImageView) findViewById(R.id.smoke_top);
mSmokeBottomImageView = (ImageView) findViewById(R.id.smoke_bottom);
// 尾气喷射设置动画效果并开启
AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
alphaAnimation.setDuration(500);
ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF,
0.5f, Animation.RELATIVE_TO_SELF, 1f);
scaleAnimation.setDuration(500);
// 动画集中添加缩放和透明动画
AnimationSet animationSet = new AnimationSet(true);
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(scaleAnimation);
mSmokeTopImageView.startAnimation(animationSet);
mSmokeBottomImageView.startAnimation(alphaAnimation);
// 1秒之后关闭当期活动
mHandler.sendEmptyMessageDelayed(0, 1000);
}
}

所对应的布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <ImageView
android:id="@+id/smoke_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/smoke_m"
android:layout_alignParentBottom="true"/> <ImageView
android:id="@+id/smoke_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@id/smoke_bottom"
android:background="@drawable/smoke_t" /> </RelativeLayout>

AndroidManifest.xml中添加相应的权限:

<!--全局弹出对话框需要添加权限-->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

效果如下所示:

主活动中只是设置俩按钮,一个开启服务,一个关闭服务,这里不再赘述,欢迎大家去GitHub上下载代码;有什么问题也可以评论交流一下;

代码地址:GitHub地址

转: https://blog.csdn.net/u010347226/article/details/77677908

Android仿腾讯手机管家实现桌面悬浮窗小火箭发射的动画效果的更多相关文章

  1. android桌面悬浮窗仿QQ手机管家加速效果

    主要还是用到了WindowManager对桌面悬浮进行管理. 需要一个火箭的悬浮窗 一个发射台悬浮窗  ,判断火箭是否放到了发射台,如果放上了,则使用AsyTask 慢慢将火箭的图片往上移.结束后., ...

  2. Android手机安全软件的恶意程序检测靠谱吗--LBE安全大师、腾讯手机管家、360手机卫士恶意软件检测方法研究

    转载请注明出处,谢谢. Android系统开放,各大论坛活跃,应用程序分发渠道广泛,这也就为恶意软件的传播提供了良好的环境.好在手机上安装了安全软件,是否能有效的检测出恶意软件呢?下边针对LBE安全大 ...

  3. Android桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果

    大家好,今天给大家带来一个仿360手机卫士悬浮窗效果的教程,在开始之前请允许我说几句不相干的废话. 不知不觉我发现自己接触Android已有近三个年头了,期间各种的成长少不了各位高手的帮助,总是有很多 ...

  4. Android 桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果

    首先是一个小的悬浮窗显示的是当前使用了百分之多少的内存,点击一下小悬浮窗,就会弹出一个大的悬浮窗,可以一键加速.好,我们现在就来模拟实现一下类似的效果. 先谈一下基本的实现原理,这种桌面悬浮窗的效果很 ...

  5. Android简易实战教程--第十话《模仿腾讯手机助手小火箭发射详解》

    之前对系统自带的土司的源码做了简要分析,见博客:点击打开链接 这一篇给一个小案例,自定义土司,模拟腾讯卫士的小火箭发射.如果想要迅速看懂代码,建议先去看一下上篇介绍点击打开链接 首先,定义一个服务,在 ...

  6. android添加桌面悬浮窗

    1. 添加权限 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> 2. ...

  7. 简易的可拖动的桌面悬浮窗效果Demo

    首先,我们需要知道,悬浮窗分为两种:Activity级别的悬浮窗,系统级别的悬浮窗 Activity级别的悬浮窗跟随所属Activity的生命周期而变化,而系统级别的悬浮窗则可以脱离Activity而 ...

  8. android桌面悬浮窗实现

                            首先是一个小的悬浮窗显示的是当前使用了百分之多少的内存,点击一下小悬浮窗,就会弹出一个大的悬浮窗,可以一键加速.好,我们现在就来模拟实现一下类似的效果. ...

  9. 【Android UI设计与开发】10:滑动菜单栏(二)SlidingMenu 动画效果的实现

    其实就是在显示菜单栏时,有个动画的效果.代码比较简单,下面进行说明. 1.效果图如下,手机上查看效果更佳 2.代码实现,这里只讲解动画效果的实现,具体代码可在源代码中查看 <1> 先定义一 ...

随机推荐

  1. Pythonic版冒泡排序和快速排序(附:直接插入排序)

    [本文出自天外归云的博客园] 冒泡排序:就是每次排序选最大元素到数组a的最后,排 len(a)-1 次.也就是两个for循环: 1. 外层是待排数组长度的循环,从待排数组长度(初始待排数组长度等于数组 ...

  2. mysql-connector-java-5.1.22下载

    java连接mysql时,需要安装驱动.如果未安装,会出现找不到“com.mysql.jdbc.Driver”的错误. 最新版驱动是:mysql-connector-java-5.1.22 下载地址: ...

  3. java基础篇---异常处理

    认识异常 异常时导致程序中断运行的一种指令流,如果不对异常进行正确的处理,则可能导致程序的中断执行,造成不必要的损失,所以在程序的设计中必须考虑各种异常的发生,并正确的做好相应的处理,这样才能保证程序 ...

  4. Android ListView的使用(一)

    初次接触listview,以为直接在Android Studio 中将控件给拖过去,就能够使用了,结果半天显示不了. 后来总算知道原因了. 先上代码: activity_main.xml 显示页面 里 ...

  5. 【应用笔记】【AN005】Qt开发环境下基于RS485的4-20mA电流采集

    简介 4-20mA电流环具有广泛的应用前景,在许多行业中都发挥着重要作用.本文主要介绍在Qt开发环境下基于RS485实现4-20mA电流采集,实现WINDOWS平台对数据的采集.分析及显示. 系统组成 ...

  6. 【UE4】VR模式下全屏(去掉两侧的黑边)

    1.下载UE4源码,用Visual Studio打开源码找到指定文件,修改代码后重新编译得到一个新的UE4编辑器 2.将游戏项目在新的UE4中打开,重新编译. 参考: https://caedmom. ...

  7. Visual Studio的NuGet包管理器无法加载

    由于网络原因,虽然地址http://www.nuget.org和https://www.nuget.org/api/v2/在浏览器可以正常打开,但是在VS中使用默认的NuGet程序包源经常加载不出来, ...

  8. WK2124 驱动移植

    官网: http://www.wkmic.com/News_Show.php?theId=17 驱动首先放在 kernel 3.2.0 driver/spi/ 下面 // 1. 更名为 wk2124A ...

  9. QButton

    Button.h #pragma once // QButton class QButton : public CButton { DECLARE_DYNAMIC(QButton) // Constr ...

  10. Unicode编码:保存中文cookie

    中文和英文字符不同,中文属于Unicod字符,在内存中站4个字符,而英文属于ASCII字符,内存中只占2个字符.Cookie中使用Unicode字符时需要对Unicode字符进行编码,否则会乱码.编码 ...