拖拽升空的Android小火箭

先上演示效果

这里写图片描述


1、MainActivity

主布局就两个Button按钮 :一开启、二关闭 就不贴主布局xml了

因为小火箭是游离在activity之外的,所以不能依赖activity的生命周期

需要注意的一点是不要忘记在清单文件里配置 service

贴一下代码:

public class MainActivity extends Activity {private Button open,close;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_main);initView();}/*** 初始化*/private void initView() {// TODO Auto-generated method stubopen = (Button) findViewById(R.id.open);close = (Button) findViewById(R.id.close);/*** 开启火箭*/open.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubstartService(new Intent(MainActivity.this,RocketService.class));finish();}});/*** 关闭火箭*/close.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubstopService(new Intent(MainActivity.this,RocketService.class));finish();}});}
}

2、RocketService 火箭服务类

该类主要是实现小火箭挂载在屏幕窗体

实现屏幕随意拖拽

拖拽到指定位置自动发射

贴代码:

/***结合1、2、3.顺序看 注释比较详细*/
public class RocketService extends Service {private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();private WindowManager mWM;private int height;private int width;private View viewToast;private ImageView iv_rocket;private AnimationDrawable drawable;@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();//获取屏幕窗体mWM = (WindowManager) getSystemService(WINDOW_SERVICE);//获取屏幕宽高height = mWM.getDefaultDisplay().getHeight();width = mWM.getDefaultDisplay().getWidth();//开启火箭showRocket();}/*** 开启小火箭*/private void showRocket() {//1、让小火箭默认在左上角显示final WindowManager.LayoutParams params = mParams;params.height = WindowManager.LayoutParams.WRAP_CONTENT;params.width = WindowManager.LayoutParams.WRAP_CONTENT;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_PHONE;params.setTitle("Toast");//指定吐司的所在位置(将吐司指定在左上角)params.gravity = Gravity.LEFT+Gravity.TOP;//2、  定义吐司layout布局 -填充给 >view挂载到屏幕上显示viewToast = View.inflate(this, R.layout.rocket_view, null);iv_rocket = (ImageView) viewToast.findViewById(R.id.iv_rocket);//拿到动画的额帧drawable = (AnimationDrawable) iv_rocket.getBackground();//iv_rocket.startAnimation(drawable);//获取背景图片后,让其动起来drawable.start();//3、图片手指拖动到额监听事件iv_rocket.setOnTouchListener(new OnTouchListener() {//开始的 x y 坐标private int startX; private int startY;@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN://获取按下的xy坐标startX = (int) event.getRawX();startY = (int) event.getRawY();break;case MotionEvent.ACTION_MOVE://获取移动xy坐标和按下的xy坐标做差,做差得到的值小火箭移动的距离//移动过程中做容错处理//第一次移动到的位置,作为第二次移动的初始位置int moveX = (int) event.getRawX();int moveY = (int) event.getRawY();//做差拿到移动距离int disX = moveX - startX;int disY = moveY - startY;//将按下的坐标+移动距离 = 当前位置重新赋值给窗体params.x = params.x+disX;params.y = params.y+disY;//在窗体中仅仅告知吐司的左上角的坐标if(params.x<0){params.x = 0;}if(params.y<0){params.y = 0;}if(params.x>width-viewToast.getWidth()){params.x = width-viewToast.getWidth();}if(params.y>height-22-viewToast.getHeight()){params.y = height-22-viewToast.getHeight();}//告知吐司在窗体上刷新mWM.updateViewLayout(viewToast, params);//在第一次移动完成后,将最终坐标作为第二次移动的起始坐标startX = (int) event.getRawX();startY = (int) event.getRawY();break;case MotionEvent.ACTION_UP://手指放开的时候,如果放手坐标,则指定区域内if(params.x>200 && params.x<300 && params.y>300){//火箭的发射sendRocket();//在开启火箭过程中,去开启一个新的activity,activity透明,在此activity中放置两张图片(淡入淡出效果)Intent intent = new Intent(getApplicationContext(),BackgroundActivity.class);//指定开启新的activity任务栈intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);}break;}return true;}});//4、将自定义的tosat布局添加到窗体管理器中mWM.addView(viewToast, params);}private Handler handler = new Handler(){public void handleMessage(Message msg) {mParams.y = (Integer) msg.obj;//更新到火箭上(窗体)mWM.updateViewLayout(viewToast, mParams);};};private void sendRocket() {new Thread(){public void run() {for(int i=0;i<11;i++){int y = 350 - i*35;//350 是当前模拟器高//睡眠try {Thread.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}//通过消息机制,将y轴坐标作为主线程火箭竖直方向上的显示位置Message msg = Message.obtain();msg.obj = y;handler.sendMessage(msg);}};}.start();}@Overridepublic void onDestroy() {if(mWM!=null && viewToast!=null){mWM.removeView(viewToast);}super.onDestroy();}@Overridepublic IBinder onBind(Intent intent) {return null;}
}

3、BackgroundActivity 小火箭尾气

该类完成小火箭发射尾气动画的实现
代码不多 主要就是一个淡入淡出的动画

public class BackgroundActivity extends Activity {private Handler mHandler = new Handler(){public void handleMessage(android.os.Message msg) {//结束此activity,销毁尾气图片finish();};};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//设置尾气图片setContentView(R.layout.activity_background);ImageView iv_top = (ImageView) findViewById(R.id.iv_top);ImageView iv_bottom = (ImageView) findViewById(R.id.iv_bottom);//尾气淡入淡出效果,动画是异步操作,并不会去阻塞主线程AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);alphaAnimation.setDuration(500);iv_top.startAnimation(alphaAnimation);iv_bottom.startAnimation(alphaAnimation);//将尾气消失,发送一个延时消息,1秒以后结束此activity,mHandler.sendEmptyMessageDelayed(0, 1000);}
}

清单文件中的注册需要加一个主题:

<activity android:theme="@android:style/Theme.Translucent.NoTitleBar"android:name="com.example.demo2_rocket.BackgroundActivity"/>

xml布局

<?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/iv_bottom"android:layout_alignParentBottom="true"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/desktop_smoke_m"/><ImageView android:id="@+id/iv_top"android:layout_above="@id/iv_bottom"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/desktop_smoke_t"/>
</RelativeLayout>

动画rocket_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" ><item android:drawable="@drawable/desktop_rocket_launch_1"android:duration="200"/> <item android:drawable="@drawable/desktop_rocket_launch_2"android:duration="200"/> 
</animation-list>

好了 完成了,就2个activity 、一个services,看代码注释完全可以看明白

Demo链接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/414892.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

yii验证系统学习记录,基于yiicms(一)写的太长了,再写一篇(二)

项目地址&#xff1a;https://gitee.com/templi/yiicms 感谢七觞酒大神的付出&#xff0c;和免费分享。当然也感谢yii2的开发团队们。 项目已经安全完毕&#xff0c;不知道后台密码&#xff0c;这种背景下&#xff0c;后台无法进去。绕不开的话题就是&#xff1a; 1.后台密码账…

前端学习(2697):重读vue电商网站18之监听图片删除事件

Js // 处理图片移除的操作 handleRemove(file) {// 1.获取将要删除的图片的临时路径const filePath file.response.data.tmp_path// 2.从pics数组中&#xff0c;找到这个图片对应的索引值const idx this.addForm.pics.findIndex(x > x.pic filePath)// 3.调用数组的 spli…

vscode开发java接口跳转到实现

我是mac系统&#xff0c;按照默认是commandF12&#xff0c;但是我的mac 13寸&#xff0c;按照这个快捷键&#xff0c;就显示亮度调节了。所以需要使用插件IntelliJ IDEA Keybindings来解决这个问题。 快捷方式如下&#xff1a;

前端学习(2698):重读vue电商网站19之处理图片预览操作

图片预览窗可以用 el-dialog 组件来做&#xff0c;然后通过 on-preview 函数来处理图片预览的操作。 Js <!-- 图片预览 --> <el-dialog title"图片预览" :visible.sync"previewVisable" width"50%"><img :src"previewPath&…

Android 集成高德地图——当前定位,添加图标,画路线,设置显示中心位置,比例,地图刷新位置监听,判断GPS开启,去打开GPS

/*** 判断定位服务是否开启** param* return true 表示开启*/ public static boolean isLocationEnabled(Context context) {int locationMode 0;String locationProviders;if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {try {locationMode Settings.Secure.…

vscode-spring-boot YAML_UNKNOWN_PROPERTY 解决

使用vscode开发&#xff0c;安装了vscode-spring-boot ,报错如下 解决方案&#xff0c;增加对yml文件的识别 新增.vscode/settings.json 内容如下&#xff1a; {"files.associations": {"*.yml": "yaml"} }

Android之Junit测试类

今天跟着视频学习了Junit测试类&#xff0c;趁热打铁、顺便把学的东西整理下来&#xff0c;再就是为了以后好回顾 1、Junit单元测试介绍&#xff1a; 在实际开发中&#xff0c;经常要对已经实现的功能进行单元测试&#xff0c;以保证当前单元没问题&#xff0c;尽可能的减少已有…

前端学习(2699):重读vue电商网站20之使用Timeline 时间线

可视化地呈现时间流信息。 由于 vue-cli-plugin-element 最后更新时间是 2019年1月&#xff0c;而 element-ui 中 Timeline 时间线更新是在 3月份&#xff0c;因此我们没有办法直接进行引用。因此&#xff0c;我们直接通过手动导入的方式。 然后&#xff0c;我们打开 element.j…

Android 高德地图根据地址获取经纬度,计算两个坐标的距离

1、到高德开放平台申请&#xff0c;获取key 高德开放平台&#xff1a;https://lbs.amap.com/ 2、下载高德定位及地址搜索SDK:https://download.csdn.net/download/meixi_android/10845407 3、项目绑定高德SDK &#xff08;1&#xff09;配置key <meta-data android:name&q…

Android中WebService的应用

1.简介 Android中的WebService 是一种基于SOAP协议的远程调用标准。通过WebService可以将不同操作系统平台&#xff0c;不同语言、不同技术整合到一起。在Android SDK中并没有提供调用WebService的库&#xff0c;因此&#xff0c;需要使用第三方类库&#xff08;KSOAP2&#x…

宝塔 nginx 配置文件的存放目录配置vue的history模式

在项目中使用vue的history模式&#xff0c;需要配置文件&#xff0c;使用到宝塔面板的服务器。现在记录存放位置。 /www/server/panel/vhost/nginx配置history模式 try_files $uri $uri/ /index.html qkbim/index.html;配置跨域 add_header Access-Control-Allow-Origin *;ad…

查看Chome浏览器中已保存的密码

好累啊&#xff0c;今天上午模拟比赛&#xff0c;敲了一上午的代码&#xff0c;真是够够的&#xff1b;想想自己自学Java&#xff0c;然后自学Android&#xff0c;到现在一直没有放弃&#xff0c;其中要感激的人有很多很多&#xff0c;指导老师等等&#xff0c;最感谢的还是现在…

vscode开发java自定义代码模版

1、打开首选项配置 2、选择全局的 3、填写自己的代码块 {// Place your 全局 snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and // description. Add comma separated ids of the languages where the snippet is applicable…

前端学习(2702):重读vue电商网站23之element-ui 如何按需导入

在element.js 文件中&#xff0c;按照如下方式&#xff0c;进行按需导入即可。然后通过 Vue.use()方法进行引用。&#xff08;优化点&#xff1a;也就是将组建导入都放在一起&#xff0c;如果组件过多的话&#xff0c;支持换行&#xff09;

Socket实现Android客户端与服务器的通信

前言&#xff1a;题目要求故写一下总结。 1.什么是Socket? 网络用语叫套接字原理是基于tcp/ip 协议的一种通信手段&#xff0c;目前题目中要求无非就是当客户端数据异常时推送给服务器报警信息 往常接下来都是先看效果图的&#xff0c;由于今天回宿舍有点早&#xff0c;准备有…

完成聊天室的私聊功能

1 完成聊天室的私聊功能 完成聊天室私聊功能。私聊功能是指&#xff0c;客户端之间可以实现一对一的聊天。 服务器端程序启动后&#xff0c;将等待客户端连接&#xff0c;界面效果如图&#xff0d;1所示&#xff1a; 图&#xff0d;1 客户端程序运行时&#xff0c;需要用户先输…

高德地图跟百度地图经纬度互转

1、高德经纬度转百度经纬度&#xff1a; "http://api.map.baidu.com/geoconv/v1/?coords"endlo","endla"&from3&to5&ak""Hi7RspVbu9xQNVUi0S7iP0OLLQbNfn""&mcode07:63:0A:B5:14:92:C6:95:43:8C:5E:78:1D:27:27…

前端学习(2703):重读vue电商网站24之配置axios

在 main.js 文件内进行配置 那么&#xff0c;此时我们就可以通过 this访问登录组件原型上 $http 方法&#xff0c;来发起对后端的请求了。

StudentManager-java+mysql学生管理系统

哎&#xff0c;还是没坚持写下来&#xff0c;时间过得也好快&#xff0c;转眼大二上学期就要结束了&#xff0c;算了&#xff0c;先附上几天写的java-mysql学生管理系统吧 先看效果图吧&#xff0c;没录动态图&#xff0c;将就着看吧 1.程序登陆&#xff0c;初始界面 2.根据名字…