利用SurfaceView实现墨迹天气雪花效果

Android使用SurfaceView实现墨迹天气的风车效果 Android使用SurfaceView实现墨迹天气的风车效果 http://blog.youkuaiyun.com/xyz_lmn/article/details/20483709 立即下载

先看看效果图吧(小雪花的图片不是特别好,见谅)!


分析: 雪花太多, 用动画实现比较复杂, 可以借助SurfaceView控件, 为啥用SurfaceView呢, 它和View的区别: SurfeceView是在一个新启的单独的线程中绘制界面(双缓冲),不会阻碍UI线程, 而View必须在主线程即UI线程中更新界面,可能会导致UI线程的阻塞.SurfaceView在处理touch事件时会创建一个队列eventquene

什么时候用view,什么时候用SurfaceView? 如果是主动的更新界面, 需要一个单独的线程重绘状态,避免UI线程阻塞,这时用View就不方便了, 可以使用SurfaceView.

废话不多说,直接上代码: 

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup;
import com.zchz.app.test.Snow;

import java.util.ArrayList;
import java.util.Random;

/**
 * 作者:Dch on 2017/3/31 10:41
 * 描述:仿墨迹天气雪花效果
 */
public class SnowingSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
    private int snow_count = 5;
    Bitmap bitmap_snows[] = new Bitmap[5];//雪花图片
    Bitmap bitmap_bg;//雪地背景

    Thread thread;

    private boolean isRunning = true;//图片是否在移动

    private float screenWidth;
    private float screenHeight;

    private static Random random = new Random();

    private ArrayList<Snow> snowArrayList1 = new ArrayList<>();
    private ArrayList<Snow> snowArrayList2 = new ArrayList<>();
    private ArrayList<Snow> snowArrayList3 = new ArrayList<>();
    private ArrayList<Snow> snowArrayList4 = new ArrayList<>();
    private ArrayList<Snow> snowArrayList5 = new ArrayList<>();

    private SurfaceHolder holder;


    public SnowingSurfaceView(Context context) {
        super(context);
        this.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        holder = getHolder();
        holder.addCallback(this);
        //设置顶层绘制surfaceview透明
        holder.setFormat(PixelFormat.RGBA_8888);

        initViewSize(context);

        initSnowImage();

        addRandowSnow();
    }

    /**
     * 初始化雪花,加载到集合中
     */
    private void addRandowSnow() {
        for (int i = 0; i < snow_count; i++) {
            snowArrayList1.add(new Snow(bitmap_snows[0],
                    random.nextFloat() * screenWidth,
                    random.nextFloat() * screenHeight,
                    8f,
                    1 - random.nextFloat() * 2
            ));
            snowArrayList2.add(new Snow(bitmap_snows[1],
                    random.nextFloat() * screenWidth,
                    random.nextFloat() * screenHeight,
                    6f,
                    1 - random.nextFloat() * 2
            ));
            snowArrayList3.add(new Snow(bitmap_snows[2],
                    random.nextFloat() * screenWidth,
                    random.nextFloat() * screenHeight,
                    4f,
                    1 - random.nextFloat() * 2
            ));
            snowArrayList4.add(new Snow(bitmap_snows[3],
                    random.nextFloat() * screenWidth,
                    random.nextFloat() * screenHeight,
                    3f,
                    1 - random.nextFloat() * 2
            ));
            snowArrayList5.add(new Snow(bitmap_snows[4],
                    random.nextFloat() * screenWidth,
                    random.nextFloat() * screenHeight,
                    2f,
                    1 - random.nextFloat() * 2
            ));
        }
    }

    /**
     * 加载雪花图片到内存中
     */
    private void initSnowImage() {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 8; /*图片长宽方向缩小倍数*/
        bitmap_snows[0] = BitmapFactory.decodeResource(getResources(), R.drawable.snow,options);
        bitmap_snows[1] = BitmapFactory.decodeResource(getResources(), R.drawable.snow2,options);
        bitmap_snows[2] = BitmapFactory.decodeResource(getResources(), R.drawable.snow,options);
        bitmap_snows[3] = BitmapFactory.decodeResource(getResources(), R.drawable.snow2,options);
        bitmap_snows[4] = BitmapFactory.decodeResource(getResources(), R.drawable.snow,options);

        bitmap_bg = BitmapFactory.decodeResource(getResources(), R.drawable.snow_bg);

    }

    private void initViewSize(Context context) {
        this.screenWidth = context.getResources().getDisplayMetrics().widthPixels;
        this.screenHeight = context.getResources().getDisplayMetrics().heightPixels;
        Log.e("屏幕宽高", screenWidth + "--" + screenHeight);
    }

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

    @Override
    public void run() {
        while (isRunning) {
            Canvas canvas = null;
            try {
                //第一步 锁定画布
                canvas = holder.lockCanvas();
                if (canvas != null) {
                    //画雪花
                    drawSnow(canvas);
                    Snow snow = null;
                    for (int i = 0;i<snow_count;i++){
                        snow = snowArrayList1.get(i);
                        snowDrop(snow);
                    }
                    for (int i = 0;i<snow_count;i++){
                        snow = snowArrayList2.get(i);
                        snowDrop(snow);
                    }
                    for (int i = 0;i<snow_count;i++){
                        snow = snowArrayList3.get(i);
                        snowDrop(snow);
                    }
                    for (int i = 0;i<snow_count;i++){
                        snow = snowArrayList4.get(i);
                        snowDrop(snow);
                    }
                    for (int i = 0;i<snow_count;i++){
                        snow = snowArrayList5.get(i);
                        snowDrop(snow);
                    }

                }


                Thread.sleep(20);
            } catch (Exception e) {

            } finally {
                if (canvas != null) {
                    holder.unlockCanvasAndPost(canvas);
                }
            }
        }
    }

    private void snowDrop(Snow snow) {
        if (snow.x > screenWidth || snow.x < 0 || snow.y > screenHeight){
            snow.x = random.nextFloat()*screenWidth;
            snow.y = 0;
        }
        snow.x += snow.offSet; // 下落水平偏移量
        snow.y += snow.speed;
    }

    private void drawSnow(Canvas canvas) {
        Paint paint = new Paint();
        paint.setAntiAlias(true); //行锯齿
        paint.setFilterBitmap(true);//防止画布抖动
        RectF rectF = new RectF(0, 0, screenWidth, screenHeight);
        canvas.drawBitmap(bitmap_bg, null, rectF, paint);
        Snow snow = null;
        for (int i = 0; i < snow_count; i++) {
            snow = snowArrayList1.get(i);
            canvas.drawBitmap(snow.bitmap, snow.x, snow.y, paint);
            snow = snowArrayList2.get(i);
            canvas.drawBitmap(snow.bitmap, snow.x, snow.y, paint);
            snow = snowArrayList3.get(i);
            canvas.drawBitmap(snow.bitmap, snow.x, snow.y, paint);
            snow = snowArrayList4.get(i);
            canvas.drawBitmap(snow.bitmap, snow.x, snow.y, paint);
            snow = snowArrayList5.get(i);
            canvas.drawBitmap(snow.bitmap, snow.x, snow.y, paint);
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        thread = new Thread(this);
        thread.start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isRunning = false;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK){
            isRunning = true;
        }
        return super.onKeyDown(keyCode, event);
    }
}
Activtity中:
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        UIUtils.setStatusbarTrans(this);
        SnowingSurfaceView snowingSurfaceView = new SnowingSurfaceView(this);
        setContentView(snowingSurfaceView);
}

Snow.java


/**
 * 作者:Dch on 2017/3/31 10:56
 * 描述:
 * 邮箱:
 */
public class Snow {

    /**
     * 雪花图片
     */
    public Bitmap bitmap;

    /**
     * 雪花开始飘落的横坐标
     */
    public float x;
    /**
     * 雪花开始飘落的纵坐标
     */
    public float y;

    /**
     * 雪花下落的速度
     */
    public float speed;

    /**
     * 雪花飘落的偏移值
     */
    public float offSet;

    public Snow(Bitmap bitmap, float x, float y, float speed, float offSet) {
        this.bitmap = bitmap;
        this.x = x;
        this.y = y;
        this.speed = speed;
        this.offSet = offSet;
    }

    public Snow() {
    }
}







        
原创android动态背景天气源码 这个实例是我在项目中抽取的一部分,开发当时耗费了好大的精力,现在把原码分享给大家。 主要实现动态背景天气,比如下雨,闪电,多云等 天气加上会动的背景,马上提高了一个档次,令人眼前一亮。 实现过程都在代码里了,android2.2 祝大家快乐! 立即下载

相关推荐

Android代码-Android使用SurfaceView实现墨迹天气的风车效果.zip

Android使用SurfaceView实现墨迹天气的风车效果.zip

使用SurfaceView模拟下雪花的动画

学习安卓笔记之自定义控件(四)——使用SurfaceView进行简单的绘制  虽然没赶上移动开发最好的时候,也没赶上最好找工作的时候,但是赶上了学习移动开发最好的时候。资料很多,大部分常见的都能搜索出一大把,当然了“下雪花动画的效果 的示例也是非常的多。今天我也来仿造一个……

LmingAn的博客 1364

Android开发摄像头SurfaceView预览 背景画图(矩形和圆形) 实现(双surfaceview,顶层画矩形框,底层预览视频)

Android开发摄像头SurfaceView预览 背景画图(矩形和圆形) 实现(双surfaceview,顶层画矩形框,底层预览视频); UI:三个按钮 预览 摄像 图片保存,预览界面 可以显示(矩形和圆形等图画)

工作中遇到的异常处理

1)Exception :shutdown failed: ENOTCONN (Transport endpoint is not connected) 问题描述: socket shutdonwOutput时出现异常,这个问题可能是多次关闭同一个socket所导致。我这里出现这个问题的原因是server端和client端都执行断开链接的操作: 一端(qt实现)执行: socket->d

大林日志 1万+

安卓SurfaceView 实现下雨效果

安卓SurfaceView 实现下雨效果,效果请看博客:https://blog.youkuaiyun.com/weixin_41549915/article/details/80257734

雪花飘落安卓实现

在安卓中使用SurfaceView来实现雪花飘落的动画效果。SurfaceView拥有独立的绘图表面,能够实现复杂而高效的界面,可以下载研究学习。

Android问题集锦之十一:Transport endpoint is not connected

当时我的模拟器是可以联网的, 而我的http连接程序是经过验证没问题的, 所以我调了好久也没有解决。 偶然发现原来问题是这样的, 我是用代理上网的,模拟器上也是设置好了代理的, 但在程序中http连接时也需要用代理, 就行下面这样就好了: //代理 Proxy proxy = new Proxy(Proxy.Type.HTTP, new Inet

懒人的技术笔记 1万+

Android利用SurfaceView实现下雨的天气动画效果

主要介绍了Android利用SurfaceView实现下雨天气效果的相关资料,文中详细介绍 SurfaceView 和 View 的区别,以及一些需要使用到 SurfaceView 的场景。需要的朋友可以参考借鉴,下面来一起看看吧。

默认墨迹天气 下雪效果

默认墨迹天气 下雪效果

未来很长,但我会努力的走下去。 1065

利用SurfaceView实现下雨与下雪动画效果详解(Kotlin语法)

主要给大家介绍了关于利用SurfaceView实现下雨与下雪动画效果的相关资料,需要一些基本的View知识和会一些基础Kotlin语法,文中给出了详细的示例代码供大家参考学习,需要的朋友们下面随着小编来一起学习学习吧。

MPC-CBF 控制原理详解

假设系统满足如下离散时间动力学模型xt1fxtutxt∈Xut∈Uxt1​fxt​ut​xt​∈Xut​∈Uxtx_txt​:状态变量,定义域为可行状态集X⊆RnX⊆Rnutu_tut​:控制输入,定义域为控制约束集U⊆RmU⊆Rm系统需满足安全约束,由如下控制障碍函数(CBF)hX→RhX→RCx∈X∣hx≥0C:=x∈X∣hx≥。

m0_54691290的博客 1178

SurfaceView攻略~~~从零开始实现打雷下雨天气特效~①

先说说写此文的背景:我以前初学android的时候,有琢磨这个SurfaceView,但是那时候真的是对android原理,多线程等等一点都不是很理解.照着网上的代码生搬硬套加上问师父,强行实现了几个功能,但是真真的理解很浅. 这次公司需求写一个随着天气而改变背景的效果,但是又觉得放动画影响性能,.好吧.那还能怎样,又不肯用动画,只能上surfaceView了

qq_37822393的博客 1058

2015年全国大学生电子设计大赛综合测评题

2015年全国大学生电子设计大赛综合测评题 题目如下: 一、555产生可调方波 555定时器是一种集成电路芯片,常被用于定时器、脉冲产生器和振荡电路。555可被作为电路中的延时器件、触发器或起振元件。 555定时器可组成单稳态电路、多稳态电路和无稳态电路。产生方波其实就是制造一个无稳态电路。 555定时器的引脚功能: 其中: DIS引脚与OUT脚电平一致 TRIG: 当此引脚电压降至1/3VCC(或由控制端决定的阈值电压)时输出端给出高电平。 THR:当此引脚电压升至2/3VCC(或由控制端决定的阈值电压

m0_47066484的博客 3万+

Android自定义控件(十)——SurfaceView实战实现天气APP背景移动效果

本文目录SurfaceView与View区别使用缓冲的Canvas绘图SurfaceView生命周期实现天气APP背景自动左右循环移动效果 SurfaceView与View区别 前面我们所有的讲解基本都是自定义View来实现各种Android的自定义控件,但编写过相机的Android程序员,肯定对SurfaceView不陌生,那什么时候该用SurfaceView呢? 我们先来看一个概念,在Andr...

李元静 1万+

线性调频LFM脉冲压缩 连续波雷达仿真&线性调频信号仿真分析压缩matlab程序源码

13、线性调频信号(LFM)压缩感知的稀疏与重构算法(OMP)的matlab仿真程序(一个可以在matlab上运行的压缩感知实例;8、具有多普勒频移的线性调频信号(知道带宽、采样频率、T使用MATLAB仿真线性调频信号即LFM,同时具有多普勒频移时,匹配滤波后的波形变化。19、CW脉冲和LFM信号Matlab仿真(这是matlab仿真程序,实现了常规雷达信号CW和线性调频信号LFM的仿真)18、lfm信号模糊函数图 matlab(用matlab 实现的线性调频信号信号(lfm)的模糊函数图)

2301_77866396的博客 400

C#与Vector XL驱动库实战:CAN通道配置与端口访问详解

本文详细解析了使用C#调用Vector XL驱动库进行CAN总线通信开发的核心步骤。重点阐述了如何通过XL_GetDriverConfig获取硬件通道信息,并厘清channelMask与accessMask的区别与转换关系,最终指导开发者正确使用XL_OpenPort函数配置并打开CAN端口,为构建稳定的汽车电子测试与诊断应用奠定基础。

weixin_28452161的博客 361

android自定义SurfaceView实现跑男动画

先看效果: 代码实现: import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import andr

MapleShao 2023

Buck电路中自举电容串联小电阻的作用

在Buck电路中,自举电容(Cboot)驱动高边MOSFET时,因寄生电感和电容会形成LC谐振回路,导致SW节点高频振铃,引发EMI问题。串联小电阻(Rboot)可引入阻尼效应,抑制振铃、改善波形和EMI性能,但会略微增加开关损耗。设计时建议预留可调电阻位(2Ω~20Ω),根据实测结果平衡效率与系统稳定性,提升电源可靠性。这一措施是优化开关电源EMC的常见实践。

硬核科技 624

android 天气动画,Android利用SurfaceView实现下雨的天气动画效果

首先是最终实现的效果图:先分析一下雨滴的实现:每个雨滴其实就是一条线,通过canvas.drawLine()绘制线(雨滴)的长度、宽度、下落速度、透明度以及位置都是在一定范围内随机生成每 draw 一次然后改变雨滴的位置然后重绘即可实现雨滴的下落效果分析完了,那么可以直接写一个类直接继承 View ,然后重写 onDraw()吗?可以看到效果图中的雨滴的下落速度很快,那么意味着每一帧都要调用 on...

weixin_34061241的博客 465

VTK:受约束的 Delaunay 2D用法实战

VTK:受约束的 Delaunay 2D用法实战程序输出程序完整源代码 程序输出 程序完整源代码 #include <vtkActor.h> #include <vtkCellArray.h> #include <vtkDelaunay2D.h> #include <vtkMath.h> #include <vtkMinimalStandardRandomSequence.h> #include <vtkNamedColors.h>

希望我的博客,能帮上你解决学习中工作中所遇到的问题 940

AUTOSAR-SOMEIP配置总结

导入arxml之后someip信号一般以“pduSomeIp”开头或者“SomeIp”开头。以某个pdu为例,设置项“Pdu Default Partition Ref”主要是根据模块设计,配置相应的Ecuc核分区。在导入arxml之后someip信号中有三个特殊的信号,形如“SdInstance”开头的信号,设置项“Pdu Default Partition Ref”主要是根据模块设计,配置相应的Ecuc核分区。“EcuC”模块主要关注“EcucPduCollection”中的“Pdus”下面的配置。

xiandang8023的博客 4651

使用 SurfaceView 实现一个下雨的天气效果

本文为转载,原文链接:http://melodyxxx.com/2017/03/07/use_surfaceview/?utm_source=tuicool&utm_medium=referral 介绍 SurfaceView 和 View 的区别,以及一些需要使用到 SurfaceView 的场景。 文章来源:itsCoder 的 WeeklyBolg 项目itsCoder主页:

qq_26279905的博客 1047

杰理AC696N系列芯片,烧录的时候烧录器连接上芯片之后电脑显示无法识别该设备,该怎么解决?

🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up!    备注: 部分问题/难题源自互联网,经过精心筛选和整理,结合数位十多年大厂实战经验资深大佬经验总结所得,数条可行方案供所需之人参考。

**My Coding Family** 1705
上一篇: Android 6.0 运行时权限处理完全解析
下一篇: android-Ultra-Pull-To-Refresh 源码解析
MrCoderr
博客等级 码龄12年 39粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值