android小火箭案例

android小火箭案例案例描述 经常看到清理内存用到这个动画 本质上是一个自定义的 toast 绑定在服务中 原理 飞机喷火效果是两个图片不停的切换形成了喷火效果 那个喷气的效果 是一个单独的 activity 背景色设置为透明 渐变的动画效果 并且在 1s 后自动结束该 activity 素材地址

大家好,我是讯享网,很高兴认识大家。
素材地址


讯享网

效果展示

在这里插入图片描述

项目结构

在这里插入图片描述

代码示例:
  • MainActivity
package com.example.rocket; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.provider.Settings; import android.support.v7.app.AppCompatActivity; import android.view.View; public class MainActivity extends AppCompatActivity { 
    @Override protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if(!Settings.canDrawOverlays(this)) { 
    startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())), 101); } } public void startRocket(View view) { 
    startService(new Intent(getApplicationContext(), RocketService.class)); finish(); } public void endRocket(View view) { 
    stopService(new Intent(getApplicationContext(), RocketService.class)); finish(); } } 

讯享网
  • RocketService
讯享网package com.example.rocket; import android.app.Service; import android.content.Intent; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.view.Display; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; public class RocketService extends Service { 
    private WindowManager mWindowManager; private int mScreenHeight; private int mScreenWidth; private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(); private View mMRocketView; private Handler mHandler = new Handler(){ 
    @Override public void handleMessage(Message msg) { 
    mParams.y = (Integer) msg.obj; mWindowManager.updateViewLayout(mMRocketView, mParams); } }; public RocketService() { 
    } @Override public IBinder onBind(Intent intent) { 
    // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { 
    mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE); Display defaultDisplay = mWindowManager.getDefaultDisplay(); Point point = new Point(); defaultDisplay.getSize(point); mScreenWidth = point.x; mScreenHeight = point.y; showRocket(); super.onCreate(); } private void showRocket() { 
    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_KEEP_SCREEN_ON; params.format = PixelFormat.TRANSPARENT; params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; params.setTitle("Toast"); params.gravity = Gravity.LEFT + Gravity.TOP; mMRocketView = View.inflate(this, R.layout.rocket_view, null); //开启动画 final ImageView mRocketView = (ImageView) mMRocketView.findViewById(R.id.iv_rocket); AnimationDrawable animationDrawable = (AnimationDrawable) mRocketView.getBackground(); animationDrawable.start(); // 挂在到window窗口 mWindowManager.addView(mMRocketView, params); mRocketView.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: //获取按下的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 > mScreenWidth - mRocketView.getWidth()) { 
    params.x = mScreenWidth - mRocketView.getWidth(); } if (params.y > mScreenHeight - 22 - mRocketView.getHeight()) { 
    params.y = mScreenHeight - 22 - mRocketView.getHeight(); } //告知吐司在窗体上刷新 mWindowManager.updateViewLayout(mMRocketView, params); //在第一次移动完成后,将最终坐标作为第二次移动的起始坐标 startX = (int) event.getRawX(); startY = (int) event.getRawY(); break; case MotionEvent.ACTION_UP: WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); Display defaultDisplay = windowManager.getDefaultDisplay(); Point point = new Point(); defaultDisplay.getSize(point); //手指放开的时候,如果放手坐标,则指定区域内 if (params.x > point.x/2 - 120 && params.x < point.x/2 - 20 && 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; } }); } private void sendRocket() { 
    new Thread(){ 
    @Override public void run() { 
    for (int i = 0; i < 11; i++) { 
    int y = 350 - i * 35; try { 
    Thread.sleep(20); } catch (Exception e) { 
    e.printStackTrace(); } Message msg = Message.obtain(); msg.obj = y; mHandler.sendMessage(msg); } } }.start(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { 
    return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { 
    if (mWindowManager != null && mMRocketView != null) { 
    mWindowManager.removeView(mMRocketView); } super.onDestroy(); } } 
  • BackgroundActivity
package com.example.rocket; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.animation.AlphaAnimation; import android.widget.ImageView; public class BackgroundActivity extends AppCompatActivity { 
    private ImageView mIvTop; private ImageView mIvBottm; 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_background); hideStatusBar(); mIvTop = (ImageView) findViewById(R.id.iv_top); mIvBottm = (ImageView) findViewById(R.id.iv_bottom); AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1); alphaAnimation.setDuration(500); mIvTop.startAnimation(alphaAnimation); mIvBottm.startAnimation(alphaAnimation); mHandler.sendEmptyMessageDelayed(0, 1000); } private void hideStatusBar() { 
    View decorView = getWindow().getDecorView(); // Hide both the navigation bar and the status bar. // SYSTEM_UI_FLAG_FULLSCREEN is only available on Android 4.1 and higher, but as // a general rule, you should design your app to hide the status bar whenever you // hide the navigation bar. int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN; decorView.setSystemUiVisibility(uiOptions); } } 
  • drawable 动画
讯享网<?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> 
  • activity_background.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".BackgroundActivity"> <ImageView android:id="@+id/iv_bottom" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginBottom="16dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:srcCompat="@drawable/desktop_smoke_m" /> <ImageView android:id="@+id/iv_top" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toTopOf="@+id/iv_bottom" app:layout_constraintEnd_toEndOf="@+id/iv_bottom" app:srcCompat="@drawable/desktop_smoke_t" /> </android.support.constraint.ConstraintLayout> 
  • activity_main.xml
讯享网<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/bt_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="80dp" android:layout_marginLeft="80dp" android:layout_marginTop="68dp" android:text="开启火箭人" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" android:onClick="startRocket"/> <Button android:id="@+id/bt_stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="80dp" android:layout_marginLeft="80dp" android:layout_marginTop="72dp" android:text="关闭火箭人" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/bt_start" android:onClick="endRocket"/> </android.support.constraint.ConstraintLayout> 
  • rocket_view.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <ImageView android:id="@+id/iv_rocket" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/rocket_bg" /> </LinearLayout> 
  • values文件夹下的colors.xml
讯享网 <?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#008577</color> <color name="colorPrimaryDark">#00574B</color> <color name="colorAccent">#D81B60</color> <color name="transparent">#0000</color> </resources> 
  • values下的styles.xml
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> <style name="MyActivityTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowNoTitle">true</item> <item name="android:windowBackground">@color/transparent</item> <item name="android:windowIsTranslucent">true</item> </style> </resources> 
  • AndroidManifest.xml
讯享网<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.rocket"> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".BackgroundActivity" android:theme="@style/MyActivityTheme"></activity> <service android:name=".RocketService" android:enabled="true" android:exported="true" /> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 
小讯
上一篇 2025-04-03 10:51
下一篇 2025-02-13 20:36

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/50928.html