Android繁星眨眼动画效果

2023-11-15

分享一个类似星星眨眼的动画效果实现方式。这里涉及到两个类,看官可直接拿来用。

StarView.java

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.VectorDrawable;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import java.util.ArrayList;
import java.util.Random;

public class StarView extends View {
    private Paint mPaint;
    private Bitmap mStarOn;
    private Bitmap mStarOff;
    private int mStarsNumber=10;
    private ArrayList<StarModel> mStarModelList = null;
    private int mCenterX, mCenterY;
    private boolean mAnimatorStatus=true;
    private Random mRandom;

    public StarView(Context context) {
        this(context, null);
    }

    public StarView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public StarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mStarOn = getBitmapFromDrawable(getContext(),android.R.drawable.star_on);
        mStarOff = getBitmapFromDrawable(getContext(), android.R.drawable.star_off);
    }

    private Bitmap getBitmapFromDrawable(Context context, int drawableId) {
        Drawable drawable = ContextCompat.getDrawable(context, drawableId);
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        } else if (drawable instanceof VectorDrawable) {
            Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
            drawable.draw(canvas);
            return bitmap;
        }

        return null;
    }

    /**
     * 设置星星图片
     * @param starOn
     * @param starOff
     */
    public void setStar(int starOn,int starOff){
        mStarOn=getBitmapFromDrawable(getContext(),starOn);
        mStarOff=getBitmapFromDrawable(getContext(),starOff);
    }

    /**
     * 设置星星数量
     * @param number 参数值范围(1-100)
     * @return 0:设置成功 -1:设置失败
     */
    public int setStarsNumber(int number){
        if(number<=0||number>100){
            return -1;
        }
        mStarsNumber=number;
        return 0;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mCenterX = getMeasuredWidth() / 2 - mStarOn.getWidth() / 2; // 90
        mCenterY = getMeasuredHeight() / 2 - mStarOn.getHeight() / 2; // 90
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.i("StarView", "onDraw");
        if (mStarModelList == null) {
            return;
        }
        calculate(canvas);
    }
    //在这个方法里会随机地去改变星星的位置和图片类型,以达到眨眼效果
    protected void calculate(Canvas canvas){
        if(mRandom==null){
            mRandom= new Random();
        }
        float angle = 0;
        int i=0;
        float startX=0,startY=0;
        for (StarModel starModel : mStarModelList) {
            i++;
            if (i == 0) {
                angle = (float) ((10 + 270) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * mRandom.nextInt(3) * 0.1f;
                startY = (float) Math.sin(angle) * mCenterY * mRandom.nextInt(3) * 0.1f;
            } else if (i == 1) {
                angle = (float) ((30 + 270) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * mRandom.nextInt(2) * 0.1f;
                startY = (float) Math.sin(angle) * mCenterY * mRandom.nextInt(3) * 0.1f;
            } 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;
            } else if (i == 3) {
                angle = (float) ((60 + 270) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * 0.13f;
                startY = (float) Math.sin(angle) * mCenterY * 0.33f;
            } else if (i == 4) {
                angle = (float) ((50) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * 0.16f;
                startY = (float) Math.sin(angle) * mCenterY * 0.17f;
            } 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;
            } else if (i == 6) {
                angle = (float) ((145) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * 0.15f;
                startY = (float) Math.sin(angle) * mCenterY * 0.28f;
            } else if (i == 7) {
                angle = (float) ((205) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * 0.15f;
                startY = (float) Math.sin(angle) * mCenterY * 0.15f;
            } else if (i == 8) {
                angle = (float) ((215) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * mRandom.nextInt(3) * 0.1f;
                startY = (float) Math.sin(angle) * mCenterY * mRandom.nextInt(3) * 0.1f;
            } else if (i == 9) {
                angle = (float) ((225) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * 0.14f;
                startY = (float) Math.sin(angle) * mCenterY * 0.15f;
            }else {
                angle = (float) ((215) * Math.PI / 180);
                startX = (float) Math.cos(angle) * mCenterX * mRandom.nextInt(3) * 0.1f;
                startY = (float) Math.sin(angle) * mCenterY * mRandom.nextInt(3) * 0.1f;
            }
            starModel.setmStartX(startX);
            starModel.setmStartY(startY);
            if (mRandom.nextInt(12) % 2 == 0) {
                starModel.setmIcon(mStarOn);
            } else {
                starModel.setmIcon(mStarOff);
            }
            starModel.draw(canvas, mPaint, mCenterX, mCenterY);
        }
    }

    /**
     * 开始动画
     * @return
     */
    public void startAnimation() {
        mAnimatorStatus=true;
        initStarModel();
        //这里开启一个线程,不断地去刷新view(调用invalidate方法后调用onDraw)
        new Thread(){
            @Override
            public void run() {
                super.run();
                while (mAnimatorStatus){
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    invalidate();
                }
            }
        }.start();
    }

    /**
     * 停止动画
     */
    public void stopAnimation() {
        mAnimatorStatus=false;
    }

    private void initStarModel() {
        Log.i("StarView","initStarModel");
        if(mStarModelList==null){
            mStarModelList = new ArrayList<>(mStarsNumber);
        }else {
            mStarModelList.clear();
        }
        Bitmap bitmap = mStarOn;
        for (int i = 0; i < mStarsNumber; i++) {
            Matrix matrix = new Matrix();
            StarModel model = new StarModel(bitmap, 0, 0, matrix);
            mStarModelList.add(model);
        }
    }
}

StarModel.java

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.Log;

public class StarModel {
    private Bitmap mIcon;// 图片
    private float mStartX;// 起始位置
    private float mStartY;// 起始位置
    private Matrix mMatrix;// 矩阵

    public StarModel(Bitmap mIcon, float mStartX, float mStartY, Matrix matrix) {
        this.mIcon = mIcon;
        this.mStartX = mStartX;
        this.mStartY = mStartY;
        this.mMatrix = matrix;
    }

    public void draw(Canvas canvas, Paint paint, int centerX, int centerY) {
        float left = centerX + mStartX;
        float top = centerY + mStartY;
        Log.i("StarModel","centerY: "+centerY+" mStartY: "+mStartY);
        Log.i("StarModel","left: "+left+" top: "+top);
        mMatrix.setTranslate(left, top);
        canvas.drawBitmap(mIcon, mMatrix, paint);
    }

    public Bitmap getmIcon() {
        return mIcon;
    }

    public void setmIcon(Bitmap mIcon) {
        this.mIcon = mIcon;
    }

    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;
    }

}

使用方法:

1,在布局文件里面加入StarView

<com.xxx.xxx.xxx.StarView
            android:id="@+id/star"
            android:layout_centerInParent="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

2,在Activity里调用

final StarView starView = findViewById(R.id.star);
starView.setStar(R.drawable.star,R.drawable.star2);
.....
start_annmotion.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                starView.startAnimation();
            }
});
findViewById(R.id.stop_annmotion).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                starView.stopAnimation();
            }
});

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android繁星眨眼动画效果 的相关文章

  • Android 应用程序因 Firebase 电话身份验证而崩溃

    我正在使用 firebase 进行电话号码身份验证 当我使用我的电话号码时 它会自动验证它 但是当我使用另一个电话号码时 我得到类转换异常 它说 getGoogleApiForMethod 返回 Gms stackoverflow上也有类似
  • 如何拦截全局资源加载?

    背景 我需要使用翻译 SDK Lokalise 文档here https docs lokalise com en articles 3487109 lokalise android sdk 2 0 beta 旨在从其服务器加载字符串资源
  • 在 Android 中获取联系方式需要花费大量时间?

    您好 目前正在做一个与联系人相关的项目 我正在从联系人中获取详细信息 电子邮件 电话号码和联系人姓名 效果很好 但问题是获取联系方式需要很长时间 超过 1000 个联系人 包括从社交网站同步的联系人 这样我就放了一个Asynchronous
  • 文件递归搜索

    我试图在根目录及其子目录中查找文件 步骤1 在指定路径中查找目录 步骤2 如果找到上述目录 则在其子目录之一中查找文件 为此 我使用下面的代码片段进行递归搜索 现在 这里的问题是 当它满足我的上述要求时 如何突破递归 boolean bFi
  • 带有 CollapsingToolbarLayout 的 PreferenceFragment

    我想要具有滚动活动的首选项片段 例如 Telegram 应用程序 我用了一个android support v7 widget RecyclerView in FrameLayout这是我的活动 xml
  • Android Wear:在手持设备上启动服务

    我正在构建一个 Wear 应用程序 它将与手持设备上的 WearableListenerService 进行通信 但是 我想确保当应用程序在手表上启动时服务已启动并运行 我最初的想法是发送意图或广播消息来启动服务 但是 我一直无法弄清楚如何
  • 如何在android中将多个图像合并为一个图像?

    我正在开发 android 的分布式应用程序 我已将单个图像分成 4 个部分 然后对其进行处理 现在我想将 4 个位图图像组合成一个图像 我怎样才能做到这一点 Bitmap parts new Bitmap 4 Bitmap result
  • AdMob 广告未显示

    因此 我使用 Play Services SDK 实施了 AdMob 广告 我已经 按照书本 做了所有事情 但广告不会显示 如果我将 AdView 背景设置为白色 它会显示空白 但不显示广告 我正在使用 Fragments 但我将 AdVi
  • SQLite 中的 NOT NULL 列和错误捕获

    我有一个由用户定义的 EditText 填充的数据库 所有编辑文本都不允许有空字段 我知道我可以通过几个简单的 if 语句来检查这一点 if myEditText getText toString equals display error
  • 在styles.xml中设置所有按钮样式

    我想让我的应用程序有多种样式 样式更改按钮样式 文本视图颜色和布局背景颜色 我的按钮样式位于 xml 文件中 这是我的代码 style xml v21
  • 删除SD卡上的文件夹

    I tried File delete 但它不起作用 如何删除SD卡上的目录 我正在开发 Android 2 1 在删除目录本身之前 您必须将所有目录清空 请参阅here http www rgagnon com javadetails j
  • 如何使用 Retrofit 2 和 RxJava 处理分页

    我知道如何处理 Retrofit 响应 但在使用 rx java 处理来自 REST API 的分页时遇到问题 背景 我使用的其余 api 为我提供了以下响应 并在标题中提供了下一页的链接 HTTP 200 OK Allow GET HEA
  • Android 上的嵌套滚动

    我们的活动中有一个主要的水平滚动视图 以及嵌套在其中的几个垂直滚动视图 这个想法是水平滚动 直到找到所需的垂直列表 然后上下滚动 理想情况下 一旦开始垂直滚动 我希望垂直滚动具有 锁定 现在会发生什么 如果您非常小心 您可以垂直滚动 但如果
  • Android - 如何设置所有屏幕的背景颜色?

    维护字体和颜色样式的最佳实践是什么 我制作了一个 color xml 文件 用于更改按钮等单独元素的颜色 但我不确定 Android 希望开发人员如何组织他们的样式 例如 我希望所有屏幕都具有相同的背景颜色 我怎么做 我需要为每个 Acti
  • Android 缩放和密度问题

    Update 一些研究表明 华硕 Transformer TF700T 高端 的像素密度应约为 224 因此 android 报告的 159 值要么是错误的 要么已被某种方式修改 system 中的 lcd 密度键 build prop 由
  • Android中从一个应用程序向另一个应用程序发送数据时的加密

    我想将敏感数据从一个应用程序发送到另一个应用程序 我使用 Intent 并通过 Bundle 发送数据 现在 我应该使用加密算法来加密要发送的数据 同时接收器应用程序将解密数据 哪种算法最适合移动平台 我浏览过RSA文档 建议不建议用于长文
  • Android HTTP PUT 请求

    谁能给我一个HTTP PUT请求 Android 的示例代码 假设您想使用 HttpURLConnection 要执行 HTTP PUT 请使用以下命令 URL url new URL http www example com resour
  • Android:了解 OnDrawFrame、FPS 和 VSync (OpenGL ES 2.0)

    一段时间以来 我在 Android 游戏中遇到了运动精灵间歇性 卡顿 的情况 这是一个非常简单的 2D OpenGL ES 2 0 游戏 这是一个持续存在的问题 我已经多次重新访问过 在我的游戏循环中 我有 2 个 计时器 一个用于记录前一
  • DOM 中不再存在缓存元素

    就像在类似的问题中一样 我使用appium java 尝试选择元素 在移动应用程序中 我要转到页面 之后有许多元素 android widget ImageView 0 我需要选择 6 个 例如 这样的元素并执行其他步骤 Byt 只能选择一
  • 切换按钮形状不变

    我正在尝试制作一个带有绿色背景的圆形切换按钮 我用了

随机推荐