iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android自定义view实现雪花特效实例代码
  • 471
分享到

Android自定义view实现雪花特效实例代码

android实现雪花特效android雪花特效android自定义view 2022-12-28 18:12:30 471人浏览 安东尼
摘要

目录一、前言二、创意名三、效果展示四、实现步骤五、编码实现总结一、前言 这个冬天,老家一直没有下雨, 正好圣诞节,就想着制作一个下雪的特效。 圣诞祝福:平安夜,舞翩阡。雪花飘,飞满天

一、前言

这个冬天,老家一直没有下雨, 正好圣诞节,就想着制作一个下雪的特效。

圣诞祝福:平安夜,舞翩阡。雪花飘,飞满天。心与心,永相伴。

圣诞节是传统的宗教节日,对于基 督徒,那是庆祝耶稣的诞生,纪念耶稣和发扬基督精神。现在整个西方社会都在过圣诞节,像许多宗教节日一样,它已经越来越民俗化了。

尽管如此,圣诞节依然倍受尊重。人们在圣诞快乐中怀有对耶稣的敬仰,欢乐的节庆里含有庄严肃穆的神念。欢度圣诞佳节的人都不拒绝耶稣的教诲,要仁爱、善良、诚实、忍耐、感恩……在信神的国度,不是基 督徒的人们,也都知道人应该感恩,心存谢意。对需要帮助的人给予关爱;对他人的帮助给予感谢。这是西方社会价值观的一部份,而不是说圣诞夜就只是一家坐在壁炉前,共进有火鸡或烤鹅的圣诞大餐或是冬季里开的一个最热闹的大派对。

二、创意名

Android实现雪花特效自定义view

三、效果展示

四、实现步骤

1.创建一个view,里面加载雪花类的集合,有一个死循环线程,一直执行动画

 public class myRunnable implements Runnable {
        @Override
        public void run() {
            while (true){
                canvas canvas =null;
                try {
                    synchronized (holder){
                        canvas = holder.lockCanvas();
                        //清除画布
                        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
                        for (Snowflake snowflake :list){
                            snowflake.draw(canvas);
                            snowflake.update();
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    if (canvas!=null){
                        holder.unlockCanvasAndPost(canvas);
                    }
                }

            }
        }
    }

这样的话,可以让所有的雪花图片动起来

2.创建雪花类,其实就是一个bitmap,然后设置不同尺寸和动画

这步相对来说简单一些,其实就是将bitmap绘制到画布上面

public void reset(){
        size = randomizer.randomInt(sizeMinInPx, sizeMaxInPx, true);
        if (image!=null){
            if (bitmap==null){
                bitmap = Bitmap.createScaledBitmap(image, size, size, false);
            }
        }
        float speed =  (float)(size - sizeMinInPx) / (sizeMaxInPx - sizeMinInPx) * (speedMax - speedMin) + speedMin;
        double angle = Math.toRadians(randomizer.randomDouble(angleMax) * randomizer.randomSignum());
        speedX = speed* Math.sin(angle);
        speedY = speed* Math.cos(angle);

        alpha = randomizer.randomInt(alphaMin, alphaMax, false);
        paint.setAlpha(alpha);

        positionX = randomizer.randomDouble(parentWidth);

        this.positionY=randomizer.randomDouble(parentHeight);
        if (!alreadyFalling){
            this.positionY = this.positionY-parentHeight-size;
        }
    }

3.界面展示

实现manifest加载视图即可

<?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"
    android:background="#000"
    tools:context="com.marvin.snowfall_master.MainActivity">

    <com.itbird.SnowfallView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/sf_snow"
        app:snowflakesNum="200"
        app:snowflakeAlphaMin="150"
        app:snowflakeAlphaMax="255"
        app:snowflakeAngleMax="5"
        app:snowflakeSizeMin="2dp"
        app:snowflakeSizeMax="40dp"
        app:snowflakeSpeedMin="2"
        app:snowflakeSpeedMax="10"
        app:snowflakesFadingEnabled="true"
        app:snowflakesAlreadyFalling="false"
        app:snowflakeImage="@mipmap/snowflake"
        />

</android.support.constraint.ConstraintLayout>

五、编码实现

界面类SnowfallView

public class SnowfallView extends SurfaceView implements SurfaceHolder.Callback {

    private int DEFAULT_SNOWFLAKES_NUM = 200;
    private int DEFAULT_SNOWFLAKE_ALPHA_MIN = 150;
    private int DEFAULT_SNOWFLAKE_ALPHA_MAX = 250;
    private int DEFAULT_SNOWFLAKE_ANGLE_MAX = 10;
    private int DEFAULT_SNOWFLAKE_SIZE_MIN_IN_DP = 2;
    private int DEFAULT_SNOWFLAKE_SIZE_MAX_IN_DP = 8;
    private int DEFAULT_SNOWFLAKE_SPEED_MIN = 2;
    private int DEFAULT_SNOWFLAKE_SPEED_MAX = 8;
    private boolean DEFAULT_SNOWFLAKES_FADING_ENABLED = false;
    private boolean DEFAULT_SNOWFLAKES_ALREADY_FALLING = false;

    private int snowflakesNum;
    private Bitmap snowflakeImage;
    private int snowflakeAlphaMin;
    private int snowflakeAlphaMax;
    private int snowflakeAngleMax;
    private int snowflakeSizeMinInPx;
    private int snowflakeSizeMaxInPx;
    private int snowflakeSpeedMin;
    private int snowflakeSpeedMax;
    private boolean snowflakesFadingEnabled;
    private boolean snowflakesAlreadyFalling;

    //雪花类集合
    private ArrayList<Snowflake> list =new ArrayList<>();

    private SnowfallView.myRunnable myRunnable = new myRunnable();
    private Thread myThread;
    private SurfaceHolder holder;


    public SnowfallView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    private void init(Context context, AttributeSet attributeSet) {
        TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.SnowfallView);
        snowflakesNum = typedArray.getInt(R.styleable.SnowfallView_snowflakesNum, DEFAULT_SNOWFLAKES_NUM);
        snowflakeImage = drawable2Bitmap(typedArray.getDrawable(R.styleable.SnowfallView_snowflakeImage));
        snowflakeAlphaMin = typedArray.getInt(R.styleable.SnowfallView_snowflakeAlphaMin, DEFAULT_SNOWFLAKE_ALPHA_MIN);
        snowflakeAlphaMax = typedArray.getInt(R.styleable.SnowfallView_snowflakeAlphaMax, DEFAULT_SNOWFLAKE_ALPHA_MAX);
        snowflakeAngleMax = typedArray.getInt(R.styleable.SnowfallView_snowflakeAngleMax, DEFAULT_SNOWFLAKE_ANGLE_MAX);
        snowflakeSizeMinInPx = typedArray.getDimensionPixelSize(R.styleable.SnowfallView_snowflakeSizeMin, dp2Px(DEFAULT_SNOWFLAKE_SIZE_MIN_IN_DP));
        snowflakeSizeMaxInPx = typedArray.getDimensionPixelSize(R.styleable.SnowfallView_snowflakeSizeMax, dp2Px(DEFAULT_SNOWFLAKE_SIZE_MAX_IN_DP));
        snowflakeSpeedMin = typedArray.getInt(R.styleable.SnowfallView_snowflakeSpeedMin, DEFAULT_SNOWFLAKE_SPEED_MIN);
        snowflakeSpeedMax = typedArray.getInt(R.styleable.SnowfallView_snowflakeSpeedMax, DEFAULT_SNOWFLAKE_SPEED_MAX);
        snowflakesFadingEnabled = typedArray.getBoolean(R.styleable.SnowfallView_snowflakesFadingEnabled, DEFAULT_SNOWFLAKES_FADING_ENABLED);
        snowflakesAlreadyFalling = typedArray.getBoolean(R.styleable.SnowfallView_snowflakesAlreadyFalling, DEFAULT_SNOWFLAKES_ALREADY_FALLING);
        typedArray.recycle();

        holder = this.getHolder();
        holder.addCallback(this);

        //设置背景为透明
        setZOrderOnTop(true);
        holder.setFORMat(PixelFormat.TRANSPARENT);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //获取雪花集合
        for (int i=0;i<snowflakesNum;i++){
            list.add(new Snowflake(w, h, snowflakeImage, snowflakeAlphaMin, snowflakeAlphaMax
                    , snowflakeAngleMax, snowflakeSizeMinInPx, snowflakeSizeMaxInPx, snowflakeSpeedMin, snowflakeSpeedMax
                    , snowflakesFadingEnabled, snowflakesAlreadyFalling));
        }
    }

    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        if (changedView==this&&visibility==GoNE){
            //初始化雪花类
            try {
                for (Snowflake snowflake :list){
                    snowflake.reset();
                }
            }catch (Exception e){
                e.printStackTrace();
            }

        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (isInEditMode()){
            return;
        }
    }

    
    private int dp2Px(int dp){
        return (int) (dp*getResources().getDisplayMetrics().density);
    }

    
    private Bitmap drawable2Bitmap(Drawable drawable){
        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());
        drawable.draw(canvas);
        return bitmap;
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        if (myThread==null){
            myThread = new Thread(myRunnable);
        }
        if(!myThread.isAlive()){
            myThread.start();
        }

    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        if (myThread!=null){
            myThread.interrupt();
        }
    }

    public class myRunnable implements Runnable {
        @Override
        public void run() {
            while (true){
                Canvas canvas =null;
                try {
                    synchronized (holder){
                        canvas = holder.lockCanvas();
                        //清除画布
                        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
                        for (Snowflake snowflake :list){
                            snowflake.draw(canvas);
                            snowflake.update();
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    if (canvas!=null){
                        holder.unlockCanvasAndPost(canvas);
                    }
                }

            }
        }
    }
}

雪花类Snowflake


public class Snowflake {

    private int parentWidth;
    private int parentHeight;
    private int alphaMin;
    private int alphaMax;
    private int angleMax;
    private int sizeMinInPx;
    private int sizeMaxInPx;
    private int speedMin;
    private int speedMax;
    private Bitmap image;
    private boolean fadingEnabled;
    private boolean alreadyFalling;

    private int size = 0 ;
    private int alpha = 255;
    private Bitmap bitmap = null;
    private double speedX= 0.0;
    private double speedY = 0.0;
    private double positionX = 0.0;
    private double positionY = 0.0;
    private final Randomizer randomizer;

    private Paint paint;

    public Snowflake(int parentWidth, int parentHeight, Bitmap image
            ,int alphaMin,int alphaMax,int angleMax,int sizeMinInPx,int sizeMaxInPx,
                    int speedMin,int speedMax,boolean fadingEnabled,boolean alreadyFalling ){
        this.parentWidth = parentWidth;
        this.parentHeight = parentHeight;
        this.alphaMin = alphaMin;
        this.alphaMax = alphaMax;
        this.angleMax = angleMax;
        this.sizeMinInPx = sizeMinInPx;
        this.sizeMaxInPx = sizeMaxInPx;
        this.speedMin = speedMin;
        this.speedMax = speedMax;
        this.image = image;
        this.fadingEnabled=fadingEnabled;
        this.alreadyFalling=alreadyFalling;

        randomizer = new Randomizer();
        initPaint();
        reset();
    }

    
    private void initPaint() {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.rgb(255,255,255));
        paint.setStyle(Paint.Style.FILL);
    }

    public void reset(double positionY){
        size = randomizer.randomInt(sizeMinInPx, sizeMaxInPx, true);
        if (image!=null){
            if (bitmap==null){
                bitmap = Bitmap.createScaledBitmap(image, size, size, false);
            }
        }
        float speed = (float)(size - sizeMinInPx) / (sizeMaxInPx - sizeMinInPx) * (speedMax - speedMin) + speedMin;

        double angle = Math.toRadians(randomizer.randomDouble(alphaMax) * randomizer.randomSignum());
        if (angle<-1||angle>1){
            angle = 0;
        }
        speedX = speed* Math.sin(angle);
        speedY = speed* Math.cos(angle);
        alpha = randomizer.randomInt(alphaMin, alphaMax, false);
        paint.setAlpha(alpha);

        positionX = randomizer.randomDouble(parentWidth);

        this.positionY = positionY;
    }

    public void reset(){
        size = randomizer.randomInt(sizeMinInPx, sizeMaxInPx, true);
        if (image!=null){
            if (bitmap==null){
                bitmap = Bitmap.createScaledBitmap(image, size, size, false);
            }
        }
        float speed =  (float)(size - sizeMinInPx) / (sizeMaxInPx - sizeMinInPx) * (speedMax - speedMin) + speedMin;
        double angle = Math.toRadians(randomizer.randomDouble(angleMax) * randomizer.randomSignum());
        speedX = speed* Math.sin(angle);
        speedY = speed* Math.cos(angle);

        alpha = randomizer.randomInt(alphaMin, alphaMax, false);
        paint.setAlpha(alpha);

        positionX = randomizer.randomDouble(parentWidth);

        this.positionY=randomizer.randomDouble(parentHeight);
        if (!alreadyFalling){
            this.positionY = this.positionY-parentHeight-size;
        }
    }

    public void update(){
        positionX = positionX+speedX;
        positionY = positionY+speedY;
        if (positionY>parentHeight){
            positionY = -(double)size;
            reset(positionY);
        }
        if (fadingEnabled){
            paint.setAlpha((int) (alpha * ((float) (parentHeight - positionY) / parentHeight)));
        }
    }

    public void draw(Canvas canvas){
        if (bitmap!=null){
            canvas.drawBitmap(bitmap,(float)positionX,(float)positionY,paint);
        }else {
            canvas.drawCircle((float)positionX,(float)positionY,(float)size,paint);
        }
    }
}

总结

到此这篇关于Android自定义view实现雪花特效的文章就介绍到这了,更多相关Android实现雪花特效内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Android自定义view实现雪花特效实例代码

本文链接: https://www.lsjlt.com/news/176120.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android自定义view实现雪花特效实例代码
    目录一、前言二、创意名三、效果展示四、实现步骤五、编码实现总结一、前言 这个冬天,老家一直没有下雨, 正好圣诞节,就想着制作一个下雪的特效。 圣诞祝福:平安夜,舞翩阡。雪花飘,飞满天...
    99+
    2022-12-28
    android实现雪花特效 android雪花特效 android自定义view
  • Android如何用自定义View实现雪花效果
    效果图 1.SnowView 类 package com.ilz.rocketapplication.handaccount.view; import android.co...
    99+
    2024-04-02
  • Android自定义View实现扫描效果
    本文实例为大家分享了Android自定义View实现扫描效果的具体代码,供大家参考,具体内容如下 演示效果如下: 实现内容: 1、控制动画是竖向或者横向 2、控制动画初始是从底部/...
    99+
    2024-04-02
  • Android自定义View实现时钟效果
    本文实例为大家分享了Android自定义View实现时钟效果的具体代码,供大家参考,具体内容如下 自定义时钟 初学自定义View,先画一个不太成熟的时钟(甚至只有秒针) 时钟效果 ...
    99+
    2024-04-02
  • Android自定义View实现标签流效果
    本文实例为大家分享了Android自定义View实现标签流效果的具体代码,供大家参考,具体内容如下 一、概述 Android自定义View实现标签流效果,一行放不下时会自动换行,用户...
    99+
    2024-04-02
  • Android自定义view实现半圆环效果
    本文实例为大家分享了Android自定义view实现半圆环的具体代码,供大家参考,具体内容如下 1.自定义属性 <declare-styleable name="Semicir...
    99+
    2024-04-02
  • Android自定义View实现水波纹效果
    介绍:水波纹散开效果的控件在 App 里面还是比较常见的,例如 网易云音乐歌曲识别,附近搜索场景。看下实现的效果:实现思路: 先将最大圆半径与最小圆半径间距分成几等份,从内到外,Paint 透明度依次递减,绘制出同心圆,然后不断的改变这些同...
    99+
    2023-05-30
    android view 水波纹
  • Android自定义view实现输入框效果
    本文实例为大家分享了Android自定义view实现输入框的具体代码,供大家参考,具体内容如下 自定义输入框的View package com.fenghongzhang.day...
    99+
    2024-04-02
  • JavaScript实现雪花飘落效果特效
    没有雪的冬天失去了冬天的美景,不见了千里冰封,万里雪飘的北国之美,诗人无从写雪,画家画不出雪景,摄影师拍不到冬天的美丽。雪,是冬天的灵魂,为大地铺好背景,之后发生的都如梦似幻,就像童...
    99+
    2023-01-01
    js雪花特效 雪花特效
  • Android自定义view之3D正方体效果实例
    目录前言一、小提二、将传感器改成事件分发机制三、使用四、源码总结前言 在之前写了一篇关于3D效果的文章,借助传感器展示,有小伙伴问可不可以改成手势滑动操作(事件分发),所以出一篇文...
    99+
    2024-04-02
  • Android自定View实现滑动验证效果的代码
    效果图 自定义属性代码 <?xml version="1.0" encoding="utf-8"?> <resources> &...
    99+
    2024-04-02
  • Android自定义View实现动画效果详解
    目录帧动画补间动画属性动画帧动画 帧动画就是给定一个完整动画的所有关键帧,由大脑想象中间的变化过程的一种动画。 <xml version="1.0" encoding="utf...
    99+
    2023-02-02
    Android自定义View实现动画 Android 动画 Android自定义View
  • Android自定义view实现滑动解锁效果
    本文实例为大家分享了Android自定义view实现滑动解锁的具体代码,供大家参考,具体内容如下 1. 需求如下: 近期需要做一个类似屏幕滑动解锁的功能,右划开始,左划暂停。 2. ...
    99+
    2024-04-02
  • Android如何实现自定义view画圆效果
    这篇文章主要介绍了Android如何实现自定义view画圆效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。看图代码:package sjx.com.custonv...
    99+
    2023-05-30
    android view
  • Android自定义View实现拖动自动吸边效果
    本文实例为大家分享了Android自定义View实现拖动自动吸边的具体代码,供大家参考,具体内容如下 自定义View,一是为了满足设计需求,二是开发者进阶的标志之一。随心所欲就是我等...
    99+
    2024-04-02
  • Android自定义View实现随机数验证码
    目录前言效果自定义 View 分类步骤1.自定义属性2.添加构造方法3.在构造里获取自定义样式4.重写 onDraw 计算坐标绘制5.重写 onMeasure 测量宽高6.设置点击事...
    99+
    2024-04-02
  • Android 自定义view实现水波纹动画效果
    在实际的开发中,很多时候还会遇到相对比较复杂的需求,比如产品妹纸或UI妹纸在哪看了个让人兴奋的效果,兴致高昂的来找你,看了之后目的很明确,当然就是希望你能给她;在这样的关键时候,身子板就一定得硬了,可千万别说不行,爷们儿怎么能说不行呢;好了...
    99+
    2023-05-31
    android 水波纹 roi
  • android自定义对话框实例代码
    1.实现效果    2.定义dialog.xml (res/layout/dialog.xml) <?xml version="1.0" encoding="utf...
    99+
    2024-04-02
  • CSS3如何实现雪花飘落特效
    这篇文章主要介绍“CSS3如何实现雪花飘落特效”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“CSS3如何实现雪花飘落特效”文章能帮助大家解决问题。在CSS3中我们可以使用animation属性来创建...
    99+
    2023-07-04
  • Android自定义view实现圆环进度条效果
    本文实例为大家分享了Android自定义view实现圆环进度条效果的具体代码,供大家参考,具体内容如下 一、实现效果图 二、核心代码 自定义view的属性 <xml vers...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作