Android实战教程第十篇仿腾讯手机助手小火箭发射效果
程序员文章站
2024-03-02 17:58:04
之前对系统自带的土司的源码做了简要分析,见博客:
这一篇给一个小案例,自定义土司,模拟腾讯卫士的小火箭发射。如果想要迅速看懂代码,建议先去看一下上篇介绍
首先,...
之前对系统自带的土司的源码做了简要分析,见博客:
这一篇给一个小案例,自定义土司,模拟腾讯卫士的小火箭发射。如果想要迅速看懂代码,建议先去看一下上篇介绍
首先,定义一个服务,在这个服务里面,完成土司的创建(小火箭布局创建),烟的效果属于动画播放,而且要依托一个activity。(这个activity要定义为透明状态)
定义烟的activity的布局文件
<?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_m" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignparentbottom="true" android:src="@drawable/desktop_smoke_m" /> <imageview android:layout_above="@id/smoke_m" android:id="@+id/smoke_t" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/desktop_smoke_t"/> </relativelayout>
在对应的smokeactivity里面加入“烟”的动画
package com.itydl.rockets; import android.app.activity; import android.os.bundle; import android.os.systemclock; import android.view.animation.alphaanimation; import android.view.animation.animation; import android.view.animation.animationset; import android.view.animation.scaleanimation; import android.widget.imageview; public class smokeactivity extends activity { @override protected void oncreate(bundle savedinstancestate) { // todo auto-generated method stub super.oncreate(savedinstancestate); setcontentview(r.layout.smoke); //底部烟图片 imageview iv_m = (imageview) findviewbyid(r.id.smoke_m); //烟柱子 imageview iv_t = (imageview) findviewbyid(r.id.smoke_t); //渐变动画 alphaanimation aa = new alphaanimation(0.0f,1.0f); aa.setduration(1000); //比例动画 设置锚点。x轴一半,y轴图片最低端y值最大处 scaleanimation sa = new scaleanimation(1.0f, 1.0f, 0.0f, 1.0f, animation.relative_to_self, 0.5f, animation.relative_to_self, 1f); sa.setduration(1000); //动画集添加动画 iv_m.startanimation(aa);//给下面这张图片实现渐变动画 animationset as = new animationset(true); as.addanimation(aa); as.addanimation(sa); //给上边图片(烟柱子)设置渐变动画和比例动画 iv_t.startanimation(as); //1秒后关闭activity,正好动画播完,关闭这个activity。这里也是那样,主线程动画的同时,子线程也在执行耗时操作 new thread(){ public void run() { //1秒后关闭当前activity systemclock.sleep(1000); runonuithread(new runnable() {//activity类中的方法 @override public void run() { // todo auto-generated method stub finish();//关闭自己也属于更新界面操作,因此要在主线程执行。 } }); }; }.start(); } }
定义service,用于自定义土司布局,加入火箭图片的动画、参数初始化、触摸事件等
package com.itydl.rockets; import android.app.service; import android.content.intent; import android.graphics.pixelformat; import android.graphics.drawable.animationdrawable; import android.os.handler; import android.os.ibinder; import android.os.systemclock; import android.view.gravity; import android.view.motionevent; import android.view.view; import android.view.view.ontouchlistener; import android.view.windowmanager; import android.widget.imageview; public class rocketservice extends service { private windowmanager.layoutparams params; private view view; private windowmanager wm; @override public ibinder onbind(intent intent) { // todo auto-generated method stub return null; } @override public void oncreate() { wm = (windowmanager) getsystemservice(window_service); //初始化params(土司参数) inittoastparams(); showrocket();//打开小火箭 super.oncreate(); } /** * 初始化土司的参数 */ private void inittoastparams() { // todo auto-generated method stub // xxx this should be changed to use a dialog, with a theme.toast // defined that sets up the layout params appropriately. params = new windowmanager.layoutparams(); params.height = windowmanager.layoutparams.wrap_content; params.width = windowmanager.layoutparams.wrap_content; //对齐方式左上角 params.gravity = gravity.left | gravity.top; params.flags = windowmanager.layoutparams.flag_not_focusable /* | windowmanager.layoutparams.flag_not_touchable */ | windowmanager.layoutparams.flag_keep_screen_on; params.format = pixelformat.translucent; params.type = windowmanager.layoutparams.type_system_alert;// 土司天生不响应事件,改变类型。type_system_alert系统弹窗 params.settitle("toast"); } private void closerocket(){ if (view != null) { wm.removeview(view);//移除小火箭 } } private handler handler = new handler(){ public void handlemessage(android.os.message msg) { wm.updateviewlayout(view, params);//更新小火箭在屏幕中的位置,刷新位置。属于更新ui。在主线程执行(更新土司的位置) }; }; private void showrocket(){ //小火箭的布局 view = view.inflate(getapplicationcontext(), r.layout.rocket, null); imageview iv_rocket = (imageview) view.findviewbyid(r.id.iv_rocket); //获取小火箭的动画背景 animationdrawable ad = (animationdrawable) iv_rocket.getbackground(); //开始小火箭动画(小火箭动画,两张图片切换) ad.start(); //给小火箭加触摸事件(给自定义土司加触摸事件),按住拖动小火箭到屏幕正下方,松开发射火箭 view.setontouchlistener(new ontouchlistener() { private float startx; private float starty; @override public boolean ontouch(view v, motionevent event) { system.out.println(event.getx() + ":" + event.getrawx()); // 拖动土司 switch (event.getaction()) { case motionevent.action_down:// 按下 startx = event.getrawx(); starty = event.getrawy(); break; case motionevent.action_move:// 按下移动,拖动 //新的 x y坐标 float movex = event.getrawx();//移动后的x坐标 float movey = event.getrawy();//移动后的y坐标 //dx x方向的位置变化值 dy y方向的位置变化值 float dx = movex - startx; float dy = movey - starty; //改变土司的坐标 params.x += dx; params.y += dy; //重新获取新的x y坐标 startx = movex; starty = movey; //更新土司的位置 wm.updateviewlayout(view, params); break; case motionevent.action_up:// 松开,接下来要发射小火箭 //判断位置 发射 //x轴方向 离两边框超过100,y轴方向大于200 就可以发射火箭 if (params.x > 100 && params.x + view.getwidth()< wm.getdefaultdisplay().getwidth() - 100 && params.y > 200){ //发射火箭 //1,火箭往上跑 //火箭在中心线上发射(自定义土司左上角为基准) params.x = (wm.getdefaultdisplay().getwidth() - view.getwidth()) / 2; new thread(){//发射火箭改变y轴属于耗时操作,更新火箭位置是更新ui操作 public void run() { for (int j = 0; j < view.getheight(); ) { systemclock.sleep(50);//休眠50毫秒 params.y -= j; j += 5; handler.obtainmessage().sendtotarget();//参数y的值改变一次,发消息通知更新一次ui,更新一次土司的位置 } //,发射完毕,关闭小火箭 stopself();//关闭服务,关闭当前自己服务。这个方法用在关闭自己服务里。触发ondestroy方法,从而触发这个方法里面的关闭小火箭 }; }.start(); //2,烟的效果。因为更新火箭往上跑是在子线程执行的,因此在小火箭往上跑的同时,烟的效果也同时开始播放(子线程不影响主线程执行。两个线程可以同时进行) //烟的效果,是一个动画,在activity完成,这个activity需要定义为透明 intent intent = new intent(rocketservice.this,smokeactivity.class); //在服务中打开activity,需要设置任务栈: intent.addflags(intent.flag_activity_new_task);//任务栈 startactivity(intent);//启动烟的activity } //冒烟的activity default: break; } return false;//默认返回值。 } }); wm.addview(view, params);//把小火箭加到窗体管理器 } @override public void ondestroy() { // todo auto-generated method stub closerocket();//关闭小火箭 super.ondestroy(); } }
对于主动人任务只是加入个按钮,打开这个服务就行了。
package com.itydl.rockets; import android.app.activity; import android.content.intent; import android.os.bundle; import android.view.view; public class mainactivity extends activity { @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); } /** * 通过点击按钮打开小火箭 * @param v */ public void openrocket(view v){ //rocketservice service = new rocketservice(); intent service = new intent(this,rocketservice.class); startservice(service);//启动小火箭服务 finish();//关闭当前界面。因为要显示火箭发射,不能在这个activity里面演示 } }
最后清单文件配置上两个活动和一个服务,还有一个弹出窗体的权限
<activity android:name="com.itheima62.rockets.mainactivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> <!-- 配置该活动的主题,为透明、无标题、全屏 --> <activity android:name="com.itheima62.rockets.smokeactivity" android:theme="@android:style/theme.translucent.notitlebar.fullscreen"></activity> <service android:name="com.itheima62.rockets.rocketservice"></service>
复制代码 代码如下:
<uses-permission android:name="android.permission.system_alert_window"/>
好了主要代码和功能都介绍完了,看一下运行效果截图:
完整代码请查看文末的原文链接。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: java抓取网页或文件中的邮箱号码