鸿蒙的学习暂且搁置了好几个月了。最近来的android的新项目。鸿蒙的加密和解密遇到一点问题。卡住了。正好这些天做了安卓项目。
安卓项目要实现一个环绕动画。查了很多资料始终没有找到合适的效果。最后在一位兄弟那里找到了自定义的动画。可惜没法点击。我自己把点击事件给加进去了。先上个效果看看。
android动画旋转效果
参考了大佬的自定义view。我修改以后加了点击事件的判断。
大佬的文章链接在这里:
Android实现旋转动画的两种方式_android 旋转动画-CSDN博客
大家可以去看大佬的原文。因为我这边的 需求是要点击某一个图片有响应。去跳转不同的产品页。大佬用的是自己画的小球。这里我改成了自己的图片。然后加了点击事件。用第一种方法实现的。第二种画布旋转的找不到点击的位置还有小球的坐标。上源码。大家可以参考下:
package com.hyw.twelveanimals.view;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import com.hyw.twelveanimals.R;
import com.hyw.twelveanimals.model.StringModel;
import com.hyw.twelveanimals.model.PointCircle;
import org.greenrobot.eventbus.EventBus;
import java.util.ArrayList;
import androidx.annotation.Nullable;
/**
* @author 最终版本---------点击坐标有响应 />
*
*
*
*/
public class MyRotateSelectView extends View {
//设置旋转间隔时间
private int SPLASH_CIRCLE_ROTATE_TIME = 30000;
//设置中心圆半径
private float CENTER_CIRCLE_RADIUS;
private float SMALL_CIRCLE_RADIUS;
private float mCurrentSingle = 0f;
private Paint mCirclePaint;
private ValueAnimator va;
int[] resArray = new int[]{R.drawable.anima1, R.drawable.anima2, R.drawable.anima3, R.drawable.anima4, R.drawable.anima5, R.drawable.anima6};
ArrayList<Bitmap> scaledBitmaps = new ArrayList<>();
public MyRotateSelectView(Context context) {
super(context);
}
public MyRotateSelectView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyRotateSelectView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
//初始化参数
initParams(width, height);
setMeasuredDimension(width, height);
}
private void initParams(int w, int h) {
//设置中心圆半径
CENTER_CIRCLE_RADIUS = 1 / 3.5f * w;
//设置小圆的半径
SMALL_CIRCLE_RADIUS = 90;
//初始化画笔
mCirclePaint = new Paint();
for (int i = 0; i < resArray.length; i++) {
Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), resArray[i]);
int desiredWidth = 180;
int desiredHeight = 180;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(originalBitmap, desiredWidth, desiredHeight, true);
scaledBitmaps.add(scaledBitmap);
}
}
ArrayList<PointCircle> arrayList = new ArrayList<>();
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制圆
drawSplashCircle(canvas);
}
private void drawSplashCircle(Canvas canvas) {
//设置属性动画,让小圆转起来
//这里得注意,是个坑,你如果不判断那球就不会动 因为会陷入死循环 值动画将值设置为0 -> invalidate()重绘 -> 执行draw 又将值设为0
if (va == null) {
va = ObjectAnimator.ofFloat(0f, 2 * (float) Math.PI);
va.setDuration(SPLASH_CIRCLE_ROTATE_TIME);
va.setRepeatCount(ValueAnimator.INFINITE);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mCurrentSingle = (float) animation.getAnimatedValue();
invalidate();
}
});
va.setInterpolator(new LinearInterpolator());
va.start();
}
//计算每个小球的间隔
double spaceAngle = Math.PI * 2 / resArray.length;
arrayList.clear();
for (int i = 0; i < resArray.length; i++) {
//利用 勾股定理 计算 小圆 中心点
float cx = getWidth() / 2 + (float) ((CENTER_CIRCLE_RADIUS) * Math.cos(spaceAngle * i + mCurrentSingle))-90;
float cy = getHeight() / 2 + (float) ((CENTER_CIRCLE_RADIUS) * Math.sin(spaceAngle * i + mCurrentSingle))-90;
canvas.drawBitmap(scaledBitmaps.get(i), cx, cy, mCirclePaint);
arrayList.add(new PointCircle(cx, cy, i));
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 获取点击位置
float x = event.getX();
float y = event.getY();
Log.e("222", "onTouchEvent: x==" + x + " y==" + y);
isInCircle(x, y);
break;
}
return true;
}
private boolean isInCircle(float x, float y) {
// 计算点到圆心的距离
for (int i = 0; i < arrayList.size(); i++) {
float cx = arrayList.get(i).getCx();
float cy = arrayList.get(i).getCy();
int p = arrayList.get(i).getI();
double distance = Math.sqrt(Math.pow(x - cx -90, 2) + Math.pow(y - cy-90 , 2));
if (distance <= 90) {
EventBus.getDefault().post(new StringModel(p));
return true;
}
}
return false;
}
}
drawable资源如果没有的话。就用安卓小机器人代替吧。
Ps-画完这个动画以后。内存吃的可厉害了。点击跳转到第二页一直报错。报xml文件错误。所有的背景图片都加载不了。一加就报错。最后报内存溢出。后来我改了半天。怀疑是内存不够了。先不执行这个动画。后面果然正常了。解决办法是在清单文件中加入:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
//加入硬件加速,否则比较卡顿
android:hardwareAccelerated="true"
//申请大内存,否则一直报内存溢出
android:largeHeap="true"
android:hardwareAccelerated="true" android:largeHeap="true"
加入这两个标签就可以正常运行了。因为我们是做大屏幕。内存这个可以随便申请。这个屏幕就跑我这一个项目。