• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Android下雪动画的实现

Android下雪动画的实现

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android动画实现,android 属性动画,android动画效果大全,android 旋转动画,android 帧动画等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Android下雪动画的实现


这本是一个愉快的季节,但是,呵呵,胡扯! 因为这篇文章的发表时间是2015年的圣诞节,所以我们需要给Style Android用制造出一些节日气氛。感谢读者们,因为有的读者可能没有在庆祝圣诞,有些读者可能还是6月份。
那么问题来了,我们应该做些什么来让这个节日像是真正的节日呢? 最简单的方法:带上圣诞帽,拍个照。

但是我感觉这个图片有些单调,所以来弄点雪花,让雪花飘下来。
我们可以添加一个包含这个图片的自定义View

res/layout/activity_main.xml

<code class="hljs xml"><!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%2D%2D%3E-->
<relativelayout android:layout_height="match_parent" android:layout_width="match_parent" tools:context="com.stylingandroid.snowfall.MainActivity" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">

  <imageview android:contentdescription="@null" android:id="@+id/image" android:layout_centerinparent="true" android:layout_height="match_parent" android:layout_width="match_parent" android:scaletype="fitCenter" android:src="@drawable/tree">

  <com.stylingandroid.snowfall.snowview android:layout_alignbottom="@id/image" android:layout_alignend="@id/image" android:layout_alignleft="@id/image" android:layout_alignright="@id/image" android:layout_alignstart="@id/image" android:layout_aligntop="@id/image" android:layout_height="match_parent" android:layout_width="match_parent">
</com.stylingandroid.snowfall.snowview></imageview></relativelayout></code>

尽管可以通过继承ImageView来实现自定义View,但我决定将 SnowView 和图片分开,这样每次刷新动画的时候不用重新渲染图片,只刷新 SnowView 就行了

SnowView.java

public class SnowView extends View {
    private static final int NUM_SNOWFLAKES = 150;
    private static final int DELAY = 5;

    private SnowFlake[] snowflakes;

    public SnowView(Context context) {
        super(context);
    }

    public SnowView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SnowView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    protected void resize(int width, int height) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.FILL);
        snowflakes = new SnowFlake[NUM_SNOWFLAKES];
        for (int i = 0; i < NUM_SNOWFLAKES; i++) {
            snowflakes[i] = SnowFlake.create(width, height, paint);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (w != oldw || h != oldh) {
            resize(w, h);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (SnowFlake snowFlake : snowflakes) {
            snowFlake.draw(canvas);
        }
        getHandler().postDelayed(runnable, DELAY);
    }

    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            invalidate();
        }
    };
}

代码很简单。 在View 的 onSizeChanged 方法中初始化 150 个随机位置的雪花对象。 在onDraw方法中画出雪花,然后每隔一段时间就刷新一下位置,需要注意的是onDraw没有立即去执行,而是通过创建一个runnable,这样不会阻塞UI线程
雪花下落是基于Samuel Arbesman的雪花下落的算法。

SnowFlake.java

class SnowFlake {
    private static final float ANGE_RANGE = 0.1f;
    private static final float HALF_ANGLE_RANGE = ANGE_RANGE / 2f;
    private static final float HALF_PI = (float) Math.PI / 2f;
    private static final float ANGLE_SEED = 25f;
    private static final float ANGLE_DIVISOR = 10000f;
    private static final float INCREMENT_LOWER = 2f;
    private static final float INCREMENT_UPPER = 4f;
    private static final float FLAKE_SIZE_LOWER = 7f;
    private static final float FLAKE_SIZE_UPPER = 20f;

    private final Random random;
    private final Point position;
    private float angle;
    private final float increment;
    private final float flakeSize;
    private final Paint paint;

    public static SnowFlake create(int width, int height, Paint paint) {
        Random random = new Random();
        int x = random.getRandom(width);
        int y = random.getRandom(height);
        Point position = new Point(x, y);
        float angle = random.getRandom(ANGLE_SEED) / ANGLE_SEED * ANGE_RANGE + HALF_PI - HALF_ANGLE_RANGE;
        float increment = random.getRandom(INCREMENT_LOWER, INCREMENT_UPPER);
        float flakeSize = random.getRandom(FLAKE_SIZE_LOWER, FLAKE_SIZE_UPPER);
        return new SnowFlake(random, position, angle, increment, flakeSize, paint);
    }

    SnowFlake(Random random, Point position, float angle, float increment, float flakeSize, Paint paint) {
        this.random = random;
        this.position = position;
        this.angle = angle;
        this.increment = increment;
        this.flakeSize = flakeSize;
        this.paint = paint;
    }

    private void move(int width, int height) {
        double x = position.x + (increment * Math.cos(angle));
        double y = position.y + (increment * Math.sin(angle));

        angle += random.getRandom(-ANGLE_SEED, ANGLE_SEED) / ANGLE_DIVISOR;

        position.set((int) x, (int) y);

        if (!isInside(width, height)) {
            reset(width);
        }
    }

    private boolean isInside(int width, int height) {
        int x = position.x;
        int y = position.y;
        return x >= -flakeSize - 1 && x + flakeSize <= width && y >= -flakeSize - 1 && y - flakeSize < height;
    }

    private void reset(int width) {
        position.x = random.getRandom(width);
        position.y = (int) (-flakeSize - 1);
        angle = random.getRandom(ANGLE_SEED) / ANGLE_SEED * ANGE_RANGE + HALF_PI - HALF_ANGLE_RANGE;
    }

    public void draw(Canvas canvas) {
        int width = canvas.getWidth();
        int height = canvas.getHeight();
        move(width, height);
        canvas.drawCircle(position.x, position.y, flakeSize, paint);
    }
}

初始化的时候,雪花的随机位置就已经确定了。这是为了确保雪花不会每次画的时候都在开始的位置。当一个雪花的位置超出Canvas的边界之后,它就会被重新放到顶部的一个随机位置,这样就可以循环利用了,避免了重复创建。
当画雪花下落的每一帧的时候,我们首先给SnowFlake添加一个随机数来改变位置,这样可以模仿有小风吹雪花。
在把雪花画到canvas上之前,我们会进行边界检查(如果需要的话,超出边界的就重新放到顶部)

我一直在不断的调整里面的常量来改变下雪的效果直到我感觉满意为止。

当然了,在canvas里面塞这么多东西不是一个好的方法(有其他更好的 比如OpenGL),但是,我现在要去吃火鸡了,所以可能要等下一次了。

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Android下雪动画的实现

相关文章

  • 2017-08-23Android实现支付宝支付
  • 2017-05-26Android之TextView,androidtextview
  • 2017-05-26Android面试题(3),android面试题
  • 2017-05-26PopupWindow的使用,PopupWindow使用
  • 2017-05-26我的android学习经历4,android学习经历4
  • 2017-05-26Git安装与上传代码至Github,git上传github
  • 2017-05-26Android自定义下拉刷新动画--仿百度外卖下拉刷新
  • 2017-05-26不带数据和返回的Activity跳转,返回activity跳转
  • 2017-05-26Android开源项目分类汇总(六)工具库
  • 2017-05-26Android 如何有效的解决内存泄漏的问题,android泄漏

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Android触摸事件(二)-TouchUtils,触摸辅助工具类
    • Android在onCreate()方法中可以获取到宽高等信息
    • 手机影音7--视频播放器的基本功能(4),7--基本功能
    • Android开发6:Service的使用(简单音乐播放器的实现),androidservice
    • debian8下apache2.4.x部署mysql认证的subversion
    • android开发中常见布局的注意点,android开发布局
    • 安卓--shape简单使用,安卓--shape
    • 购物车动画(Android),购物车动画android
    • 想要在launcher中模拟按home键。,launcherhome
    • Android广播机制

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有