java做绿色数字雨_数字雨
這篇文章介紹一個有趣的數字雨的view
先上效果圖
GIF.gif
這個效果是在逛gitbug的時候發現,流動的數字雨頗有駭客的意味。
查看代碼發現實現起來相當簡單.
看著滿屏的數字不斷變化,實際上你只需要關注某一列的數字變化即可。而每一列的數字變化實現的原理就是每隔一個新的時間點,在原有的基礎上多繪制一個數字。比如原來一列顯示兩個數字,下一個時間點顯示三個數字,這樣就能達到數字流動的視覺效果。
不多說了,直接上代碼.
分兩個步驟
1.將整個界面劃分成多個列,用來承載數字
創建NumberRainView.java
public class NumberRainView extends LinearLayout {
private int normalColor = Color.GREEN;
private int highLightColor = Color.WHITE;
private Context context;
private float textSize;
public NumberRainView(Context context) {
this(context, null);
}
public NumberRainView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.context = context;
textSize = 15 * context.getResources().getDisplayMetrics().density;
if (attrs != null) {
TypedArray typedArray = this.getContext().obtainStyledAttributes(attrs, R.styleable.NumberRainView);
normalColor = typedArray.getColor(R.styleable.NumberRainView_normalColor, Color.GREEN);
highLightColor = typedArray.getColor(R.styleable.NumberRainView_highLightColor, Color.WHITE);
textSize = typedArray.getDimension(R.styleable.NumberRainView_textSize, textSize);
typedArray.recycle();
}
setOrientation(LinearLayout.HORIZONTAL);
setBackgroundColor(Color.BLACK);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
addRainItems();
}
//核心代碼
private void addRainItems() {
int count = (int) (getMeasuredWidth() / textSize);
for (int i = 0; i < count; i++) {
NumberRainItemView itemView = new NumberRainItemView(context);
itemView.setNormalColor(normalColor);
itemView.setHighLightColor(highLightColor);
itemView.setTextSize(textSize);
itemView.setStartDelay((long) (Math.random() * 1000));
LayoutParams params = new LayoutParams((int) textSize + 10, getMeasuredHeight());
addView(itemView, params);
}
}
}
2.繪制每一列的隨機數字,同時要注意有一個高亮的數字
創建 NumberRainItemView.java
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setTextSize(textSize);
mPaint.setColor(normalColor);
if (isShowAllNumbers()) {
drawAllNumbers(canvas);
} else {
drawPartNumbers(canvas);
}
}
判斷是顯示部分數字還是所有數字,最開始的時候,只顯示部分數字,隨著時間,才會顯示完整的數字
//判斷條件
private boolean isShowAllNumbers() {
return nowHeight >= getHeight();
}
//顯示所有數字,根據view的高度來計算count
private void drawAllNumbers(Canvas canvas) {
int count = (int) (getHeight() / textSize);
drawSingleNumber(canvas, count);
}
//只顯示部分數字,根據當前的變量值nowHeight計算count
private void drawPartNumbers(Canvas canvas) {
int count = (int) (nowHeight / textSize);
nowHeight += textSize;
drawSingleNumber(canvas, count);
}
開始繪制數字
private void drawSingleNumber(Canvas canvas, int count) {
if (count == 0) {
//這段延遲為了達到各列數字雨不同步的效果
postInvalidateDelayed(startDelay);
} else {
float numberOffset = 0f;
for (int i = 0; i < count; i++) {
String randomNumber = String.valueOf((int) (Math.random() * 2));
//高亮的字符串
mPaint.setColor(highLightIndex == i ? highLightColor : normalColor);
//核心代碼,繪制文字,且不停的變化繪制的位置
canvas.drawText(randomNumber, 0, numberOffset, mPaint);
numberOffset += textSize;
}
//計算下一次的高亮位置
if (isShowAllNumbers()) {
highLightIndex++;
highLightIndex = highLightIndex % count;
} else {
highLightIndex++;
}
postInvalidateDelayed(100);
}
}
完整代碼
NumberRainItemView.java
public class NumberRainItemView extends View {
private int normalColor = Color.GREEN;
private int highLightColor = Color.RED;
private float nowHeight;
private float textSize;
private long startDelay;
private Paint mPaint;
private int highLightIndex;
public NumberRainItemView(Context context) {
super(context);
textSize = 15 * getResources().getDisplayMetrics().density;
mPaint = new Paint();
}
public void setNormalColor(int normalColor) {
this.normalColor = normalColor;
}
public void setHighLightColor(int highLightColor) {
this.highLightColor = highLightColor;
}
public void setTextSize(float textSize) {
this.textSize = textSize;
}
public void setStartDelay(long startDelay) {
this.startDelay = startDelay;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setTextSize(textSize);
mPaint.setColor(normalColor);
if (isShowAllNumbers()) {
drawAllNumbers(canvas);
} else {
drawPartNumbers(canvas);
}
}
private void drawAllNumbers(Canvas canvas) {
int count = (int) (getHeight() / textSize);
drawSingleNumber(canvas, count);
}
private void drawPartNumbers(Canvas canvas) {
int count = (int) (nowHeight / textSize);
nowHeight += textSize;
drawSingleNumber(canvas, count);
}
private void drawSingleNumber(Canvas canvas, int count) {
if (count == 0) {
postInvalidateDelayed(startDelay);
} else {
float numberOffset = 0f;
for (int i = 0; i < count; i++) {
String randomNumber = String.valueOf((int) (Math.random() * 2));
mPaint.setColor(highLightIndex == i ? highLightColor : normalColor);
canvas.drawText(randomNumber, 0, numberOffset, mPaint);
numberOffset += textSize;
}
if (isShowAllNumbers()) {
highLightIndex++;
highLightIndex = highLightIndex % count;
} else {
highLightIndex++;
}
postInvalidateDelayed(100);
}
}
private boolean isShowAllNumbers() {
return nowHeight >= getHeight();
}
}
attrs屬性
相關鏈接
最后給出一個原始地址 kotlin版
java版
總結
以上是生活随笔為你收集整理的java做绿色数字雨_数字雨的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MFC Windows程序设计 读书笔记
- 下一篇: MATLAB画图——基础篇