博主声明:

转载请在开头附加本文链接及作者信息,并标记为转载。本文由博主 威威喵 原创,请多支持与指教。

本文首发于此   博主:威威喵  |  博客主页:https://blog.csdn.net/smile_running

在开始制作代码雨效果之前呢,先来看看 Android 提供的另一种 View,它是 View 的孪生兄弟:SurfaceView 那它 与 View 有什么区别呢,我们来介绍一下。

我们都非常熟悉 View 了吧,向 TextView、ImageView、ListView 等等,它们都有一个共同的点:那就是等待用户指定的行为进行刷新或者处理一些其他 View 相关操作,举个例,比如我要让 TextView 或者 ImageView 的内容发生更新的话,那可能需要通过一个 Button 点击一下,然后才刷新文字或者图片,这就是 View 的被动更新。

那么 SurfaceView 既然与它是孪生兄弟,必定有所相同也有所不同。相同点就不用我多说了吧,View 的一些基本功能它都有,我们来看看它们的不同点的体现。

首先 SurfaceView 它是主动更新的,这与 View 不同。SurfaceView 既然是主动更新,其内部肯定会开启一个子线程,与 View 不同的是:View 它在主线程上执行的绘制,SurfaceView 在子线程执行的绘制。从它们的这一点区别来看,我们可以得出这样一个结论,如果需要主动的更新,或者说动画复杂且实时进行刷新的话,那我们的选择就偏向于 SurfaceView。

    上面介绍了一下关于 SurfaceView  的特点,下面我们来看看它如何实现吧。在小时候,看电影或电视里面的黑客片段时,给我留下最深刻印象的是满屏的代码雨效果,那黑色的背景、绿色的字母,然后在那刷刷刷的不停,就给我一种非常酷炫的感觉。哇,这个黑客好厉害,我长大也要当一名黑客。可最终被现实打败了,做了一个码农,嘻嘻。

好吧,码农也就黑客的追求,下面我们来简单的利用 SurfaceView 实现一下满屏代码雨刷刷刷的效果吧,且看效果先:

乍一看,这个效果还挺酷炫的,一大堆字母在往下坠落,但其实并非如此,至少我是不这样实现的。其实这种效果利用了我们人眼睛的反应时间,在刷新足够快的情况下,给我们一种感觉就是,这些字母一直在往下掉。其实都是在原来的坐标在进行不断的随机字母,也能达到这样的效果。当然,我这里是这样做的。

接下来是 SurfaceView 的基本用法,这个肯定要会,而且这也是一套 SurfaceView 模板,放在哪用都可以的。看代码:

package nd.no.xww.qqmessagedragview;import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;import java.util.Random;/*** @author xww* @desciption : SurfaceView 代码雨效果* @date 2019/8/6* @time 8:45*/
public class CodeRainSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {private SurfaceHolder mHolder;private Canvas mCanvas;private Paint mPaint;private boolean isDrawing;private int mWidth;private int mHeight;private void init() {mHolder = getHolder();mHolder.addCallback(this);setFocusable(true);//获得焦点setFocusableInTouchMode(true);//可触摸setKeepScreenOn(true);//屏幕常亮mPaint = new Paint();mPaint.setColor(Color.GREEN);mPaint.setTextSize(45f);mPaint.setDither(true);mPaint.setAntiAlias(true);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mWidth = MeasureSpec.getSize(widthMeasureSpec);mHeight = MeasureSpec.getSize(heightMeasureSpec);}public CodeRainSurfaceView(Context context) {this(context, null);}public CodeRainSurfaceView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public CodeRainSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}@Overridepublic void surfaceCreated(SurfaceHolder holder) {isDrawing = true;new Thread(this).start();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {isDrawing = false;}@SuppressLint("WrongCall")@Overridepublic void run() {while (isDrawing) {
//            try {onDraw();
//                Thread.sleep(16);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }}}private void onDraw() {try {mCanvas = mHolder.lockCanvas();mCanvas.drawColor(Color.BLACK);} catch (Exception e) {e.printStackTrace();} finally {if (mCanvas != null)mHolder.unlockCanvasAndPost(mCanvas);}}}

进行解释一下上面的代码,SurfaceView 的一个 Canvas 实例是从 SurfaceHolder 里获取的,也就是代码中的 lockCanvas() 需要注意的是,此方法获取的 Canvas 都是上一次保留下来的内容。举个例子,比如我上一次绘制的是一个 “威威喵” 文本,然后下一次绘制的是 “csdn” 这个文本,那么这两次绘制结果都将被保留,屏幕上会出现 “威威猫 csdn” 。那么解决办法就是采用 canvas 绘制一层颜色,如上面的 drawColor 给覆盖上去,这样就间接等于把 SurfaceView “黑板” 给擦除了。

因为 SurfaceView 是一直在刷新的,所以要实现 Runnable 接口,让子线程死循环。当然了,这里有一个 isDrawing 表示符,会根据 SurfaceView 的生命周期回掉情况来控制子线程。

好了,SurfaceView 基本使用也就这样了,其实也很简单。那么,要想实现代码雨的效果,首先肯定是 26 个字母不停的在改变,要利用 Random 随机数。然后我们需要布满整个屏幕,这里要用到画笔,画笔的宽度就是每一个字母的宽度,我们可以获取 SurfaceView 的宽度,然后去除于画笔的宽度即可,这个就是横向的一排字母,那么竖向的也是如此。

        mCodeHorCount = (int) (mWidth / mPaintSize);mCodeVerCount = (int) (mHeight / mPaintSize);

接下来就是把屏幕画满字母了,两个循环搞定

    private void drawCode(Canvas canvas) {for (int i = 0; i < mCodeHorCount; i++) {for (int j = 0; j < mCodeVerCount; j++) {canvas.drawText(LETTERS[mRandom.nextInt(26)], codeX * i, codeY + mPaintSize * j, mPaint);}}}

其他的就没什么了,每个坐标上的字母一直在随机 26 个字母就好了,来看完整的代码

package nd.no.xww.qqmessagedragview;import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;import java.util.Random;/*** @author xww* @desciption : SurfaceView 代码雨效果* @date 2019/8/6* @time 8:45*/
public class CodeRainSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {private SurfaceHolder mHolder;private Canvas mCanvas;private Paint mPaint;private float mPaintSize;// 每一行画字母的个数private int mCodeHorCount;private int mCodeVerCount;private boolean isDrawing;private final String[] LETTERS = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P","Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};private int mWidth;private int mHeight;private int codeX;private int codeY;private Random mRandom;private void init() {mHolder = getHolder();mHolder.addCallback(this);setFocusable(true);//获得焦点setFocusableInTouchMode(true);//可触摸setKeepScreenOn(true);//屏幕常亮mPaint = new Paint();mPaint.setColor(Color.GREEN);mPaint.setTextSize(45f);mPaint.setDither(true);mPaint.setAntiAlias(true);mPaintSize = mPaint.getTextSize();codeX = codeY = (int) mPaintSize;mRandom = new Random();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mWidth = MeasureSpec.getSize(widthMeasureSpec);mHeight = MeasureSpec.getSize(heightMeasureSpec);mCodeHorCount = (int) (mWidth / mPaintSize);mCodeVerCount = (int) (mHeight / mPaintSize);}public CodeRainSurfaceView(Context context) {this(context, null);}public CodeRainSurfaceView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public CodeRainSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}@Overridepublic void surfaceCreated(SurfaceHolder holder) {isDrawing = true;new Thread(this).start();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {isDrawing = false;}@SuppressLint("WrongCall")@Overridepublic void run() {while (isDrawing) {onDraw();}}private void onDraw() {try {mCanvas = mHolder.lockCanvas();mCanvas.drawColor(Color.BLACK);drawCode(mCanvas);} catch (Exception e) {e.printStackTrace();} finally {if (mCanvas != null)mHolder.unlockCanvasAndPost(mCanvas);}}private void drawCode(Canvas canvas) {for (int i = 0; i < mCodeHorCount; i++) {for (int j = 0; j < mCodeVerCount; j++) {canvas.drawText(LETTERS[mRandom.nextInt(26)], codeX * i, codeY + mPaintSize * j, mPaint);}}}
}

当然了,我们并非都是全字母的形式,还是可以加上 0 ~ 9 的数字的,只要换个数组即可

    private final String[] LETTERS_AND_NUMBER = new String[]{"A", "B", "C", "0", "D", "E", "F", "1", "G", "H", "2", "I", "J", "3", "K", "L", "4", "M", "N", "O", "P","5", "Q", "R", "6", "S", "7", "T", "U", "8", "V", "W", "9", "X", "Y", "Z"};

效果会好一点吧

那么至此,赶紧去运行一下看看效果吧,体验一把小时候看电影里面那种代码雨的感觉,哈哈。

SurfaceView 之满屏的代码雨效果相关推荐

  1. vbs代码炫酷效果_Python|实现黑客帝国代码雨效果

    Python|实现黑客帝国代码雨效果 估计大家都看过电影<黑客帝国>吧,片中的一段代码雨片段实在是炫酷,试想一下,片中的代码雨效果在自己电脑屏幕上实现了会是一种什么样的感觉,会不会有种身临 ...

  2. linux如何安装黑客帝国cmatrix代码雨效果

    linux如何安装黑客帝国cmatrix代码雨效果 cmatrix常用命令 cmatrix下载:安装包 具体步骤 源码安装cmatrix 创建/usr/local/temp目录 mkdir -p /u ...

  3. Python使用turtle库绘制动态满屏爱心代码

    情人节绘制爱心最合适了,但是单单画一个心形怎么能够满足?今天我们尝试用Python的turtle库画出一整个画布的爱心,让它们在上面动态移动.最终效果如下: 绘制爱心 画爱心有很多种画法,我这里用的方 ...

  4. Python动态满屏爱心形代码

    import os import time def heart_animation():     heart = [         "  ❤️   ❤️ ",         & ...

  5. qq满屏飞吻代码_教你用微信隐藏代码表白!各种微信技巧

    阅读本文前,请您先点击上面的"蓝色字体",再点击"关注",这样您就可以继续免费收到文章了.每天都会有分享,都是免费订阅,请您放心关注.注:本文转载自网络,不代表 ...

  6. python命令数字雨_用Python实现黑客帝国代码雨效果(3种方式)

    说起电影<黑客帝国>,相信大部分人都看过或听说过,影片中有一个场景数字雨,如果你看过电影的话,应该对这个经典场景印象深刻,本文我们利用 Python 以数字.字母.图片三种形式来实现这一效 ...

  7. html宽度满屏,宽度满屏的代码怎么样写?

    使用这个,注意路径中不要使用中文 object id=player classid=CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6 style=width: 68 ...

  8. JQuery实现——黑客帝国代码雨效果

    效果如你所见就是本页面上方那样的效果 实现方法来自一个印度小伙纸,学习完我也没总结一下,今儿个补上 如何实现,大家右键查看源码复制即可,不过学习的过程还是要总结总结. 下面通过另外两个小例子,一步一步 ...

  9. qq满屏飞吻代码_[爱情][飞吻][跳跳][爱心][嘴唇][玫瑰][月亮][礼物][拥抱]什么意思...

    满意答案 fd5g4f 2015.10.29 采纳率:56%    等级:9 已帮助:965人 [em]e数字[/em]比如: 微笑: [em]e100[/em] 100微笑 101撇嘴 102色 1 ...

  10. 微信首页制作代码Android,微信满屏代码

    微信满屏代码软件可以在微信或者qq的聊天栏中产生各种代码乱飞或者流行坠落的图案,小西整理了各种好玩又好看的微信满屏代码,用起来也会非常的有意思的,另外还有独特的技巧提供给大家. 微信满屏代码说明 主要 ...

最新文章

  1. free5GC — 部署端到端 5G 实验网络
  2. 实战SSM_O2O商铺_21【商铺列表】Dao层开发
  3. 1038 Recover the Smallest Number (30 分)【难度: 中 / 知识点: 贪心 思维】
  4. 这两天说到的苹果软件中毒是个什么情况?
  5. Eclipse-不显示某些文件夹
  6. Selenium2+python自动化35-获取元素属性
  7. 【写作技巧】计算机应用技术毕业论文范文
  8. 新手学习算法----二叉树(将一个二叉查找树按照中序遍历转换成双向链表)
  9. js 时间格式与时间戳的相互转换示例代码
  10. 20200710每日一句
  11. Android平台Camera实时滤镜实现方法探讨(八)--滤镜基本制作方法(二)简单美颜滤镜...
  12. ffmpeg用法及如何使用fluent-ffmpeg
  13. Qt之 QStringLiteral
  14. Linux高性能服务器架构
  15. 单、多通道图像反差处理
  16. 软件工程Alpha冲刺day7
  17. c51单片机光电门测反应时间(实战小项目)
  18. 天龙八部手游服务器等级哪里显示,天龙八部手游
  19. 防灾科技学院的计算机如何,防灾科技学院最好的专业是什么
  20. Axure初学者——好用的网站和技巧

热门文章

  1. 安卓udp发包工具_好装逼牌udp-tcp发包工具
  2. C/C++经典项目开发:教你破解Windows系统密码,手把手教你做解密项目
  3. 几何画板如何画曲线方程?
  4. DOOM启世录的启示
  5. javascript 高级程序设计 (第四版) 第二章 下
  6. 1400协议是什么和28181区别_支持对接GB28181吗?监控,智能摄像头,国标推流,RTSP...
  7. OSI参考模型在网络系统中的应用浅析
  8. TCPIP详解之udp
  9. 教师资格证面试结构化面试100题
  10. 基于深度学习生成音乐(mid格式)