//星星外圈的控件
public class RingView extends View {
private final static String TAG = “RingView”;
private int mDuration = 5000;
private float mCx;
private float mCy;
private float mMaxRadius; // 最大半径
private float mOuterCurrentProgress;
private float mInnerCurrentProgress;
private int[] mColors;
private PorterDuffXfermode mXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
private Paint mPaint; // 绘制外圆
private Paint mInnerPaint;
public RingView(Context context) {
this(context, null);
}
public RingView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public RingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mColors = getContext().getResources().getIntArray(R.array.clor_ring);
mPaint = new Paint();
mPaint.setColor(mColors[0]);
mInnerPaint = new Paint();
mInnerPaint.setColor(Color.TRANSPARENT);
mInnerPaint.setAlpha(0);
mInnerPaint.setXfermode(mXfermode);
}
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mCx = getMeasuredWidth() / 2;
mCy = getMeasuredHeight() / 2;
mMaxRadius = mCx;
}
@Override protected void onDraw(Canvas canvas) {
int saveLayer = canvas.saveLayer(0, 0, mCx * 2, mCy * 2, mPaint, Canvas.ALL_SAVE_FLAG);
canvas.drawCircle(mCx, mCx, mOuterCurrentProgress * mMaxRadius, mPaint);
canvas.drawCircle(mCx, mCy, mInnerCurrentProgress * mMaxRadius, mInnerPaint);
canvas.restoreToCount(saveLayer);
}
public void startAnim(int duration) {
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1f);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override public void onAnimationUpdate(ValueAnimator animation) {
mOuterCurrentProgress = (float) animation.getAnimatedValue();
mPaint.setARGB(255, 255, (int) (229 - mOuterCurrentProgress * 68), 0);
invalidate();
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator()); // 先变快,然后减速
ValueAnimator innerAnimator = ValueAnimator.ofFloat(0.01f, 1f);
innerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override public void onAnimationUpdate(ValueAnimator animation) {
mInnerCurrentProgress = (float) animation.getAnimatedValue();
invalidate();
}
});
innerAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(duration);
animatorSet.playTogether(valueAnimator, innerAnimator);
animatorSet.start();
}
private OnWillEndAnimatorListener onWillEndAnimatorListener;
public void setOnWillEndAnimatorListener(OnWillEndAnimatorListener onWillEndAnimatorListener) {
this.onWillEndAnimatorListener = onWillEndAnimatorListener;
}
public interface OnWillEndAnimatorListener {
void onWillEndAnimatorListener(float value);
}
}
//工具类
public class ScreenUtils {
public static float SCALE = 0.92f;
private ScreenUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
/**
* Return the width of screen, in pixel.
*
* @return the width of screen, in pixel
*/
public static int getScreenWidth() {
WindowManager wm = (WindowManager) App.getApplication().getSystemService(Context.WINDOW_SERVICE);
Point point = new Point();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
// noinspection ConstantConditions
wm.getDefaultDisplay().getRealSize(point);
} else {
// noinspection ConstantConditions
wm.getDefaultDisplay().getSize(point);
}
return point.x;
}
/**
* Return the height of screen, in pixel.
*
* @return the height of screen, in pixel
*/
public static int getScreenHeight() {
WindowManager wm = (WindowManager) App.getApplication().getSystemService(Context.WINDOW_SERVICE);
Point point = new Point();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
// noinspection ConstantConditions
wm.getDefaultDisplay().getRealSize(point);
} else {
// noinspection ConstantConditions
wm.getDefaultDisplay().getSize(point);
}
return point.y;
}
/**
* Return the density of screen.
*
* @return the density of screen
*/
public static float getScreenDensity() {
return Resources.getSystem().getDisplayMetrics().density;
}
/**
* Return the screen density expressed as dots-per-inch.
*
* @return the screen density expressed as dots-per-inch
*/
public static int getScreenDensityDpi() {
return Resources.getSystem().getDisplayMetrics().densityDpi;
}
/**
* Set full screen.
*
* @param activity
* The activity.
*/
public static void setFullScreen(@NonNull final Activity activity) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
/**
* Set non full screen.
*
* @param activity
* The activity.
*/
public static void setNonFullScreen(@NonNull final Activity activity) {
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
/**
* Toggle full screen.
*
* @param activity
* The activity.
*/
public static void toggleFullScreen(@NonNull final Activity activity) {
int fullScreenFlag = WindowManager.LayoutParams.FLAG_FULLSCREEN;
Window window = activity.getWindow();
if ((window.getAttributes().flags & fullScreenFlag) == fullScreenFlag) {
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
} else {
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
}
/**
* Return whether screen is full.
*
* @param activity
* The activity.
* @return {@code true}: yes<br>
* {@code false}: no
*/
public static boolean isFullScreen(@NonNull final Activity activity) {
int fullScreenFlag = WindowManager.LayoutParams.FLAG_FULLSCREEN;
return (activity.getWindow().getAttributes().flags & fullScreenFlag) == fullScreenFlag;
}
/**
* Set the screen to landscape.
*
* @param activity
* The activity.
*/
public static void setLandscape(@NonNull final Activity activity) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
/**
* Set the screen to portrait.
*
* @param activity
* The activity.
*/
public static void setPortrait(@NonNull final Activity activity) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
/**
* Return whether screen is landscape.
*
* @return {@code true}: yes<br>
* {@code false}: no
*/
public static boolean isLandscape() {
return App.getApplication().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
}
/**
* Return whether screen is portrait.
*
* @return {@code true}: yes<br>
* {@code false}: no
*/
public static boolean isPortrait() {
return App.getApplication().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
}
/**
* Return the rotation of screen.
*
* @param activity
* The activity.
* @return the rotation of screen
*/
public static int getScreenRotation(@NonNull final Activity activity) {
switch (activity.getWindowManager().getDefaultDisplay().getRotation()) {
case Surface.ROTATION_0:
return 0;
case Surface.ROTATION_90:
return 90;
case Surface.ROTATION_180:
return 180;
case Surface.ROTATION_270:
return 270;
default:
return 0;
}
}
/**
* Return the bitmap of screen.
*
* @param activity
* The activity.
* @return the bitmap of screen
*/
public static Bitmap screenShot(@NonNull final Activity activity) {
return screenShot(activity, false);
}
/**
* Return the bitmap of screen.
*
* @param activity
* The activity.
* @param isDeleteStatusBar
* True to delete status bar, false otherwise.
* @return the bitmap of screen
*/
public static Bitmap screenShot(@NonNull final Activity activity, boolean isDeleteStatusBar) {
View decorView = activity.getWindow().getDecorView();
decorView.setDrawingCacheEnabled(true);
decorView.setWillNotCacheDrawing(false);
Bitmap bmp = decorView.getDrawingCache();
if (bmp == null) return null;
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
Bitmap ret;
if (isDeleteStatusBar) {
Resources resources = activity.getResources();
int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
int statusBarHeight = resources.getDimensionPixelSize(resourceId);
ret = Bitmap.createBitmap(bmp, 0, statusBarHeight, dm.widthPixels, dm.heightPixels - statusBarHeight);
} else {
ret = Bitmap.createBitmap(bmp, 0, 0, dm.widthPixels, dm.heightPixels);
}
decorView.destroyDrawingCache();
return ret;
}
/**
* Return whether screen is locked.
*
* @return {@code true}: yes<br>
* {@code false}: no
*/
public static boolean isScreenLock() {
KeyguardManager km = (KeyguardManager) App.getApplication().getSystemService(Context.KEYGUARD_SERVICE);
// noinspection ConstantConditions
return km.inKeyguardRestrictedInputMode();
}
public static int dp2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
/**
* 宽高比例
*
* @return
*/
public static float wrradioH() {
int height = ScreenUtils.getScreenHeight();
int width = ScreenUtils.getScreenWidth();
return (float) width / height;
}
public static int getDimens(Context mContext, @DimenRes int id) {
return mContext.getResources().getDimensionPixelOffset(id);
}
}
//动画的工具类
public class StarModel {
private Bitmap mIcon; // icon
private double mStarAngle; // 开始角度
private float mStartX; // 起始位置
private float mStartY; // 起始位置
private Matrix mMatrix; // 矩阵
private float mInitScale; // 初始化缩放值
private float mSpeed; // 加速度
public StarModel(Bitmap mIcon, double mStarAngle, float mStartX, float mStartY, Matrix matrix, float initScale, float speed) {
this.mIcon = mIcon;
this.mStarAngle = mStarAngle;
this.mStartX = mStartX;
this.mStartY = mStartY;
this.mMatrix = matrix;
this.mInitScale = initScale;
this.mSpeed = speed;
}
public void draw(Canvas canvas, Paint paint, float currentProgress, int centerX, int centerY) {
// 路径问题
float left = (float) (centerX + mStartX + Math.cos(mStarAngle) * (Math.abs(centerX - Math.abs(mStartX))) * currentProgress * mSpeed); // 初始角度
float top = (float) (centerY + mStartY + Math.sin(mStarAngle) * (Math.abs(centerY - Math.abs(mStartY))) * currentProgress * mSpeed);
mMatrix.setTranslate(left, top);
float scale = mInitScale - currentProgress;
if (scale < 0) {
scale = 0;
}
mMatrix.preScale(scale, scale);
canvas.drawBitmap(mIcon, mMatrix, paint);
}
public Bitmap getmIcon() {
return mIcon;
}
public void setmIcon(Bitmap mIcon) {
this.mIcon = mIcon;
}
public double getmStarAngle() {
return mStarAngle;
}
public void setmStarAngle(double mStarAngle) {
this.mStarAngle = mStarAngle;
}
public float getmStartX() {
return mStartX;
}
public void setmStartX(float mStartX) {
this.mStartX = mStartX;
}
public float getmStartY() {
return mStartY;
}
public void setmStartY(float mStartY) {
this.mStartY = mStartY;
}
public Matrix getmMatrix() {
return mMatrix;
}
public void setmMatrix(Matrix mMatrix) {
this.mMatrix = mMatrix;
}
}
//弹出的小星星、
public class StarView extends View {
private Paint mPaint;
private Bitmap mStar; // 星星图片
private ArrayList<StarModel> mStarModelList = null;
private float mCurrentProgress; // 当前进度
private int mCenterX, mCenterY; // 中心点
private ValueAnimator mValueAnimator;
public StarView(Context context) {
this(context, null);
}
public StarView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public StarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mStar = BitmapFactory.decodeResource(getResources(), R.mipmap.stars1);
}
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mCenterX = getMeasuredWidth() / 2 - mStar.getWidth() / 2; // 90
mCenterY = getMeasuredHeight() / 2 - mStar.getHeight() / 2; // 90
}
@Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mStarModelList == null) {
return;
}
for (StarModel starModel : mStarModelList) {
starModel.draw(canvas, mPaint, mCurrentProgress, mCenterX, mCenterY);
}
}
public ValueAnimator startAnimation(int length, int duration, int delay) {
if (mStarModelList != null) {
mStarModelList.clear();
mValueAnimator = null;
}
initStarModel(length);
mValueAnimator = ValueAnimator.ofFloat(0f, 1f);
mValueAnimator.setInterpolator(new DecelerateInterpolator());
mValueAnimator.setDuration(duration);
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override public void onAnimationUpdate(ValueAnimator animation) {
mCurrentProgress = (float) animation.getAnimatedValue();
invalidate();
}
});
mValueAnimator.setStartDelay(delay);
mValueAnimator.start();
return mValueAnimator;
}
private void initStarModel(int length) {
mStarModelList = new ArrayList<>(10);
Random random = new Random();
for (int i = 0; i < length; i++) {
float angle = 0f;
float startX = 0f;
float startY = 0f;
float speed = 1 + random.nextInt(5); // 总共是19
float scale = 1f; // 开始大小
if (i == 0) {
angle = (float) ((10 + 270) * Math.PI / 180);
startX = (float) Math.cos(angle) * mCenterX * 0.05f;
startY = (float) Math.sin(angle) * mCenterY * 0.5f;
// speed = 0.5789f;
} else if (i == 1) {
angle = (float) ((30 + 270) * Math.PI / 180);
startX = (float) Math.cos(angle) * mCenterX * 0.1f;
startY = (float) Math.sin(angle) * mCenterY * 0.2f;
// speed = 0.7368f;
} else if (i == 2) {
angle = (float) ((40 + 270) * Math.PI / 180);
startX = (float) Math.cos(angle) * mCenterX * 0.25f;
startY = (float) Math.sin(angle) * mCenterY * 0.4f;
// speed = 0.5789f;
} else if (i == 3) {
angle = (float) ((60 + 270) * Math.PI / 180);
startX = (float) Math.cos(angle) * mCenterX * 0.3f;
startY = (float) Math.sin(angle) * mCenterY * 0.33f;
// speed = 0.5263f;
} else if (i == 4) { // 星星变小
angle = (float) ((50) * Math.PI / 180);
startX = (float) Math.cos(angle) * mCenterX * 0.6f;
startY = (float) Math.sin(angle) * mCenterY * 0.7f;
scale = 0.8f;
// speed = 0.3157f; // 8
} else if (i == 5) { // 星星变更小
angle = (float) ((80) * Math.PI / 180);
startX = (float) Math.cos(angle) * mCenterX * 0.05f;
startY = (float) Math.sin(angle) * mCenterY * 0.3f;
scale = 0.6f;
// speed = 0.4210f;
} else if (i == 6) {
angle = (float) ((145) * Math.PI / 180);
startX = (float) Math.cos(angle) * mCenterX * 0.5f;
startY = (float) Math.sin(angle) * mCenterY * 0.28f;
// speed = 0.5263f;
} else if (i == 7) {
angle = (float) ((205) * Math.PI / 180);
startX = (float) Math.cos(angle) * mCenterX * 0.5f;
startY = (float) Math.sin(angle) * mCenterY * 0.15f;
scale = 0.8f;
// speed = 0.4210f;
} else if (i == 8) {
angle = (float) ((215) * Math.PI / 180);
startX = (float) Math.cos(angle) * mCenterX * 0.8f;
startY = (float) Math.sin(angle) * mCenterY * 0.35f;
// speed = 0.5789f;
} else if (i == 9) {
angle = (float) ((225) * Math.PI / 180);
startX = (float) Math.cos(angle) * mCenterX * 0.4f;
startY = (float) Math.sin(angle) * mCenterY * 0.5f;
// speed = 0.5789f;
}
Matrix matrix = new Matrix();
StarModel model = new StarModel(mStar, angle, startX, startY, matrix, scale, speed);
mStarModelList.add(model);
}
}
}
//动画
package administration.utils.star;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.animation.BounceInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class StarLayout extends FrameLayout {
public StarLayout(@NonNull Context context) {
this(context, null);
}
public StarLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public StarLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void startRingAnim(final int[] originLocation, ImageView idIvBigStar1,
RingView idRingView1, StarView idSmallStarListView1,
int startAnim, int startend) {
final int[] location = new int[2];
idIvBigStar1.post(new Runnable() {
@Override
public void run() {
idIvBigStar1.getLocationInWindow(location);
final int disX = originLocation[0] - location[0];
final int disY = originLocation[1] - location[1];
idIvBigStar1.setAlpha(0f);
idRingView1.startAnim(startAnim);
startBigStarScaleAnim(startend, 0,idIvBigStar1).start();
idSmallStarListView1.startAnimation(10, 1600, 300);
startBitStarTransAndScaleAnim(disX, disY, 1000, 1100,idIvBigStar1);
}
});
}
private Animator startBigStarScaleAnim(int duration, int startDelay, ImageView idIvBigStar1) {
ValueAnimator valueAnimator = ValueAnimator.ofFloat(1f, 5f, 8f);
valueAnimator.setInterpolator(new BounceInterpolator());
valueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
idIvBigStar1.setAlpha(1f);
}
});
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
idIvBigStar1.setScaleX(value);
idIvBigStar1.setScaleY(value);
}
});
valueAnimator.setDuration(duration);
valueAnimator.setStartDelay(startDelay);
return valueAnimator;
}
/***
* 平移并且缩放动画
*/
private void startBitStarTransAndScaleAnim(final int disX, final int disY, int duration, int delay, ImageView idIvBigStar1) {
ValueAnimator scaleAnim = ValueAnimator.ofFloat(8f, 1f);
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
idIvBigStar1.setScaleX(value);
idIvBigStar1.setScaleY(value);
}
});
ValueAnimator transAnim = ValueAnimator.ofFloat(0, 1f);
transAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
idIvBigStar1.setTranslationX(value * disX);
idIvBigStar1.setTranslationY(value * disY);
}
});
AnimatorSet animatorSet = new AnimatorSet();
// animatorSet.play(scaleAnim).with(transAnim);
animatorSet.setDuration(duration);
animatorSet.setStartDelay(delay);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) { // 动画执行完毕
if (onAnimationEnd != null) {
Log.e("TAG", "onAnimationEnd: 大多数");
onAnimationEnd.onAnimationEnd();
}
}
});
animatorSet.start();
}
private OnAnimationEnd onAnimationEnd;
public void setOnAnimationEnd(OnAnimationEnd onAnimationEnd) {
this.onAnimationEnd = onAnimationEnd;
}
public interface OnAnimationEnd {
void onAnimationEnd();//动画结束
}
}
//MainActivity
public class MainActivity extends AppCompatActivity{
@BindView(R.id.mGameteststarView3)
StarView mGameteststarView;
@BindView(R.id.mGametestringview2)
RingView mGametestringview;
@BindView(R.id.mGameteststar2)
ImageView mGameteststar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(R.layout.activity_main);
startStar(mGameteststar, mGametestringview, mGameteststarView, 400, 1200);
}
public void startStar(ImageView idIvBigStar0,
RingView idRingView0,
StarView idSmallStarListView0,
int startAnim,
int startend) {
FrameLayout decorView = (FrameLayout) getWindow().getDecorView();
StarLayout starLayout = new StarLayout(this);
starLayout.setOnAnimationEnd(new StarLayout.OnAnimationEnd() {
@Override
public void onAnimationEnd() {
Log.e("TAG", "onAnimationEnd: dsad");
//星星结束的调动
}
});
decorView.addView(starLayout);
int[] starInWindow = new int[2];
starInWindow[0] = ScreenUtils.getScreenWidth();
starInWindow[1] = ScreenUtils.getScreenHeight();
starLayout.startRingAnim(starInWindow, idIvBigStar0, idRingView0, idSmallStarListView0, startAnim, startend);
}
}
<?xml version="1.0" encoding="utf-8"?> <FrameLayout
android:layout_width="160dp"
android:layout_height="155dp"
android:layout_marginTop="57dp"
android:layout_toRightOf="@id/mGametestFra">
<administration.utils.star.StarView
android:id="@+id/mGameteststarView3"
android:layout_width="160dp"
android:layout_height="155dp"
android:layout_gravity="center" />
<ImageView
android:id="@+id/mGameteststar3"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:src="@mipmap/icon_gameteststarfalse2" />
<administration.utils.star.RingView
android:id="@+id/mGametestringview3"
android:layout_width="160dp"
android:layout_height="160dp"
android:layout_gravity="center" />
</FrameLayout>
![在这里插入图片描述](https://img-blog.csdnimg.cn/56a5bb0764314aff8e95956546e12f19.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW96aGFuZzA0MTQ=,size_16,color_FFFFFF,t_70) ![在这里插入图片描述](https://img-blog.csdnimg.cn/27bd5a7d026d4aa4824b907321dff535.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW96aGFuZzA0MTQ=,size_16,color_FFFFFF,t_70)