miui卸载爆炸效果
来源:互联网 发布:阿里云dns 多ip 编辑:程序博客网 时间:2024/04/30 18:15
package com.example.sss;import android.annotation.SuppressLint;import android.app.Activity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;public class MainActivity extends Activity { private ExplosionField mExplosionField; @SuppressLint("ResourceAsColor")@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mExplosionField = ExplosionField.attach2Window(this); addListener(findViewById(R.id.root)); } /** * 为root中除了ViewGroup的控件都添加点击事件,点击后执行爆炸效果 * @param root */ private void addListener(View root) { if (root instanceof ViewGroup) { ViewGroup parent = (ViewGroup) root; for (int i = 0; i < parent.getChildCount(); i++) { addListener(parent.getChildAt(i)); } } else { root.setClickable(true); root.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mExplosionField.explode(v); v.setOnClickListener(null); } }); } } public void click(View v){ View root = findViewById(R.id.root); reset(root); addListener(root); mExplosionField.clear(); } private void reset(View root) { if (root instanceof ViewGroup) { ViewGroup parent = (ViewGroup) root; for (int i = 0; i < parent.getChildCount(); i++) { reset(parent.getChildAt(i)); } } else { root.setScaleX(1); root.setScaleY(1); root.setAlpha(1); } }}
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" android:background="#fff" > <RelativeLayout android:layout_width="match_parent" android:layout_height="48dp" android:background="@color/colorPrimary" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题" android:textSize="20sp" android:textColor="#fff" android:layout_centerInParent="true"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="返回" android:layout_centerVertical="true" android:textColor="#fff" /> </RelativeLayout> <LinearLayout android:id="@+id/root" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="48dp" android:orientation="horizontal"> <ImageView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:clickable="true" android:src="@drawable/p1" /> <ImageView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:clickable="true" android:src="@drawable/p6" /> <ImageView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:src="@drawable/p2" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="48dp" android:orientation="horizontal"> <ImageView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:clickable="true" android:src="@drawable/p4" /> <ImageView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:src="@drawable/p5" /> <ImageView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:src="@drawable/p3" /> </LinearLayout> <TextView android:layout_width="match_parent" android:gravity="center" android:layout_marginTop="48dp" android:text="click to destroy" android:layout_height="wrap_content" /></LinearLayout> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="重置" android:onClick="click"/></LinearLayout>
/* * Copyright (C) 2015 tyrantgit * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.example.sss;import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.animation.ValueAnimator;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Rect;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;import android.view.Window;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.Random;/** * 原理: 在activity上覆盖一个ExplosionField控件,在该控件上绘制爆照粒子 * @author young * */public class ExplosionField extends View {//一个activity中只有一个ExplosionField,但可以同时在ExplosionField上绘制多个爆炸效果 private List<ExplosionAnimator> mExplosions = new ArrayList<>(); private int[] mExpandInset = new int[2]; public ExplosionField(Context context) { super(context); init(); } public ExplosionField(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ExplosionField(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { Arrays.fill(mExpandInset, Utils.dp2Px(32)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); for (ExplosionAnimator explosion : mExplosions) { explosion.draw(canvas); } } public void expandExplosionBound(int dx, int dy) { mExpandInset[0] = dx; mExpandInset[1] = dy; } public void explode(Bitmap bitmap, Rect bound, long startDelay, long duration) { final ExplosionAnimator explosion = new ExplosionAnimator(this, bitmap, bound); explosion.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mExplosions.remove(animation); } }); explosion.setStartDelay(startDelay); explosion.setDuration(duration); mExplosions.add(explosion); explosion.start(); } /** * 执行爆炸 * @param view */ public void explode(final View view) { Rect r = new Rect(); view.getGlobalVisibleRect(r); int[] location = new int[2]; getLocationOnScreen(location); r.offset(-location[0], -location[1]); r.inset(-mExpandInset[0], -mExpandInset[1]); int startDelay = 100; //爆炸前的抖动效果 ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f).setDuration(150); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { Random random = new Random(); @Override public void onAnimationUpdate(ValueAnimator animation) { view.setTranslationX((random.nextFloat() - 0.5f) * view.getWidth() * 0.05f); view.setTranslationY((random.nextFloat() - 0.5f) * view.getHeight() * 0.05f); } }); animator.start(); //抖动结束后用150毫秒把view缩小到看不到 view.animate().setDuration(150).setStartDelay(startDelay).scaleX(0f).scaleY(0f).alpha(0f).start(); explode(Utils.createBitmapFromView(view), r, startDelay, ExplosionAnimator.DEFAULT_DURATION); } public void clear() { mExplosions.clear(); invalidate(); } /** * 把该View添加到Activity中 * @param activity * @return */ public static ExplosionField attach2Window(Activity activity) { //rootView是一个FrameLayout,也可以使用activityactivity.getWindow().getDecorView()来获取,获取到的是用户通过setContentView设置的 布局 的 父布局 ViewGroup rootView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT); System.out.println("rootview = "+rootView); ExplosionField explosionField = new ExplosionField(activity); //添加进去 rootView.addView(explosionField, new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); return explosionField; }}
/* * Copyright (C) 2015 tyrantgit * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.sss;import android.animation.ValueAnimator;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.view.View;import android.view.animation.AccelerateInterpolator;import android.view.animation.Interpolator;import java.util.Random;public class ExplosionAnimator extends ValueAnimator { static long DEFAULT_DURATION = 0x400; private static final Interpolator DEFAULT_INTERPOLATOR = new AccelerateInterpolator(0.6f); private static final float END_VALUE = 1.4f; private static final float X = Utils.dp2Px(5); private static final float Y = Utils.dp2Px(20); private static final float V = Utils.dp2Px(2); private static final float W = Utils.dp2Px(1); private Paint mPaint; private Particle[] mParticles; private Rect mBound; private View mContainer; public ExplosionAnimator(View container, Bitmap bitmap, Rect bound) { mPaint = new Paint(); mBound = new Rect(bound); int partLen = 15; mParticles = new Particle[partLen * partLen]; Random random = new Random(System.currentTimeMillis()); //把图片横向分成17份,每份的宽度 int w = bitmap.getWidth() / (partLen + 2); //把图片纵向分成17份,每份的宽度 int h = bitmap.getHeight() / (partLen + 2); //总共分成了17*17块,从图片中每块(不包含边界块)的顶点的像素取出颜色后创建该颜色的粒子,然后保存到一维数组mParticles中 for (int i = 0; i < partLen; i++) { for (int j = 0; j < partLen; j++) { mParticles[(i * partLen) + j] = generateParticle(bitmap.getPixel((j + 1) * w, (i + 1) * h), random); } } mContainer = container; setFloatValues(0f, END_VALUE); setInterpolator(DEFAULT_INTERPOLATOR); setDuration(DEFAULT_DURATION); } /** * 生成粒子 * @param color * @param random * @return */ private Particle generateParticle(int color, Random random) { Particle particle = new Particle(); particle.color = color; particle.radius = V; if (random.nextFloat() < 0.2f) { particle.baseRadius = V + ((X - V) * random.nextFloat()); } else { particle.baseRadius = W + ((V - W) * random.nextFloat()); } float nextFloat = random.nextFloat(); particle.top = mBound.height() * ((0.18f * random.nextFloat()) + 0.2f); particle.top = nextFloat < 0.2f ? particle.top : particle.top + ((particle.top * 0.2f) * random.nextFloat()); particle.bottom = (mBound.height() * (random.nextFloat() - 0.5f)) * 1.8f; float f = nextFloat < 0.2f ? particle.bottom : nextFloat < 0.8f ? particle.bottom * 0.6f : particle.bottom * 0.3f; particle.bottom = f; particle.mag = 4.0f * particle.top / particle.bottom; particle.neg = (-particle.mag) / particle.bottom; f = mBound.centerX() + (Y * (random.nextFloat() - 0.5f)); particle.baseCx = f; particle.cx = f; f = mBound.centerY() + (Y * (random.nextFloat() - 0.5f)); particle.baseCy = f; particle.cy = f; particle.life = END_VALUE / 10 * random.nextFloat(); particle.overflow = 0.4f * random.nextFloat(); particle.alpha = 1f; return particle; } /* * 该属性动画只是起到一个计时作用,与爆炸效果没有其他联系。若动画时间还没结束,则依次计算每个粒子当前的各属性值(坐标,半径),然后依次绘制每个粒子 * ( canvas.drawCircle(particle.cx, particle.cy, particle.radius, mPaint); ), * 然后调用mContainer.invalidate(),调用该函数后,会自动调用mContainer(即 ExplosionField对象)的onDraw(Canvas canvas) 方法,该方法内部 * 又调用了explosion(即 ExplosionAnimator对象)的draw方法(即 下面的方法),所以又会继续绘制。所以ExplosionAnimator的draw()和ExplosionField的onDraw * 反复相互调用,直到动画时间终止为止。 这种相互调用方式跟scroller和computeScroll(),onDraw()之间的使用方式很像 */ public boolean draw(Canvas canvas) { /* * 属性动画是否结束。 */ if (!isStarted()) { return false; } for (Particle particle : mParticles) { particle.advance((Float) getAnimatedValue()); if (particle.alpha > 0f) { mPaint.setColor(particle.color); mPaint.setAlpha((int) (Color.alpha(particle.color) * particle.alpha)); canvas.drawCircle(particle.cx, particle.cy, particle.radius, mPaint);//画到ExplosionField上 } } mContainer.invalidate(); return true; } /** * 该方法是ExplosionAnimator重写过的 </br> * {@inheritDoc} * */ @Override public void start() { //开启计时 super.start(); //开始绘制粒子 mContainer.invalidate(mBound); } /** * 爆炸粒子 * */ private class Particle { float alpha; int color; float cx;//粒子当前中心x坐标 float cy;//粒子当前中心y坐标 float radius; float baseCx;//粒子原始x坐标 float baseCy;//粒子原始y坐标 float baseRadius;//粒子原始半径 float top; float bottom; float mag; float neg; float life; float overflow; /** * 计算爆炸后该粒子的圆心坐标和半径 * @param factor 因子 */ public void advance(float factor) { float f = 0f; float normalization = factor / END_VALUE; if (normalization < life || normalization > 1f - overflow) { alpha = 0f; return; } normalization = (normalization - life) / (1f - life - overflow); float f2 = normalization * END_VALUE; if (normalization >= 0.7f) { f = (normalization - 0.7f) / 0.3f; } alpha = 1f - f; f = bottom * f2; cx = baseCx + f; cy = (float) (baseCy - this.neg * Math.pow(f, 2.0)) - f * mag; radius = V + (baseRadius - V) * f2; } }}
/* * Copyright (C) 2015 tyrantgit * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.example.sss;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.ColorDrawable;import android.graphics.drawable.Drawable;import android.view.View;import android.widget.ImageView;public class Utils { private Utils() { } private static final float DENSITY = Resources.getSystem().getDisplayMetrics().density; private static final Canvas sCanvas = new Canvas(); public static int dp2Px(int dp) { return Math.round(dp * DENSITY); } /** * 把View画到Bitmap上返回 * @param view * @return */ public static Bitmap createBitmapFromView(View view) { if (view instanceof ImageView) { /** * Drawable是一个描述图片样子的类,只是描述,所以颜色等也可以是一个Drawable,若是ColorDrawable则需要创建bitmap,并把颜色绘制到bitmap上, * 下面只是简单处理了一下当时BitmapDrawable,并没有处理是ColorDrawable时。其实获取view的镜像也可以采用这种方法: * view.setDrawingCacheEnabled(true);Bitmap bitmap=Bitmap.createBitmap(view.getDrawingCache());view.setDrawingCacheEnabled(false);return bitmap; * */ Drawable drawable = ((ImageView) view).getDrawable(); if (drawable != null && drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } } view.clearFocus(); Bitmap bitmap = createBitmapSafely(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888, 1); if (bitmap != null) { synchronized (sCanvas) { Canvas canvas = sCanvas; canvas.setBitmap(bitmap); view.draw(canvas);//手动调用view的draw将导致view被绘制到了空白的bitmap上 canvas.setBitmap(null); } } return bitmap; } /** * 当创建图片导致内存溢出时,并且尝试次数没达到retryCount时,回收内存,再次执行创建, * @param width * @param height * @param config * @param retryCount * @return */ public static Bitmap createBitmapSafely(int width, int height, Bitmap.Config config, int retryCount) { try { //创建指定width*height大小,并且颜色是config的空白图片 return Bitmap.createBitmap(width, height, config); } catch (OutOfMemoryError e) { e.printStackTrace(); if (retryCount > 0) { System.gc();//建议虚拟机回收内存 return createBitmapSafely(width, height, config, retryCount - 1); } return null; } }}
0 0
- miui卸载爆炸效果
- 仿小米卸载程序时图标的爆炸效果
- Android特效专辑(五)——自定义圆形头像和仿MIUI卸载动画—粒子爆炸
- Android特效专辑(五)——自定义圆形头像和仿MIUI卸载动画—粒子爆炸
- 【Android】图标爆炸效果(类似小米卸载应用图标散开效果)
- MIUI拖动效果
- 制作爆炸效果
- 图片爆炸效果
- PS制作爆炸效果
- Box2d实现爆炸效果
- 爆炸的效果(IOS)
- 飞机爆炸效果
- View粒子爆炸效果
- 物体爆炸效果的实现
- PS爆炸效果(下)
- QtQuick3D-例子-shaders-爆炸效果
- view爆炸的烟花效果
- Core Animation - 爆炸效果
- 10种软件滤波程序
- Export Eclipse Product 的一些小事
- Android下保存异常信息到SD卡中并上传服务器
- linux命令学习(3):pwd命令(当前工作目录)
- tomcat配置文件server.xml详解
- miui卸载爆炸效果
- DES加密算法原理
- C++ STL学习之queue
- getopt的用法与optarg
- Source code for SIFT, ORB, FAST and FFME for OpenCV C++ for egomotion estimation
- CocoaPods安装出现的错误
- cron表达式使用
- Win7下PhoneGap配置及简单示例
- Android LayoutInflater原理分析,带你一步步深入了解View(一)