First look at the effect:
First, the realization principle
In the implementation process, the main consideration of the entire interface consists of a number of letters of the sub-bus bar, so that a fixed number of letters encapsulated into a letter line, and each letter is encapsulated into an object, so that the formation of the following composition effect:
Alphabetic Object--"Letter Line Object"--Interface effect
Each letter should know its location coordinates, its own letters, and its own transparency:
Class hackcode{point
p = new Point ()//every letter coordinates
int alpha = 255;//Transparency value default 255
String code = "A";//Letter Value
}
Each sub bar object has its own initial bottom starting point for the line, and multiple letters inside are arranged according to the initial bottom starting point of the line, containing a collection of multiple alphabetic objects and the only indication of the line:
Class hackline{public
int NUM = 0;//is used to record the label of this column
private point P = new points (), and/or the initial position of the line
list
Creates all the child bus bar objects and the alphabetic objects in the collection when initialized:
@Override
protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {
super.onmeasure ( Widthmeasurespec, Heightmeasurespec);
Mwidth = Getmeasuredwidth ();//Get control width high
mheight = Getmeasuredheight ();
Mhacklines.clear ()//Empty collection
initplaydata ()//Initialize playback data
}
/**
* Initialize playback data
/public void Initplaydata () {
inithackline (MWIDTH/9, MHEIGHT/12);
Inithackline (MWIDTH/9, MHEIGHT/7);
Hackline HL;
for (int i = 3; i < 9; i++) {
hl= new hackline ();
hl.p.x = mwidth/9* (i+1);
HL.P.Y = mheight/7* (9-i);
for (int j = 0; J < 7; J +) {
Hackcode HC = new Hackcode ();
Hc.alpha-= 30*j;
Hc.code = Codes[new Random (). Nextint (Codes.length)];
hc.p.x = hl.p.x;
HC.P.Y = hl.p.y-dip2px (GetContext (), *j);
Hl.hcs.add (hc);
}
Mhacklines.add (HL);
hl. NUM = Mhacklines.size ();
}
}
Then draw in the onDraw
method:
@Override
protected void OnDraw (Canvas Canvas) {
for (int i = 0; i < mhacklines.size (); i++) {
DrawText (i) canvas);
}
Mhandler.sendemptymessagedelayed (WHAT, 100);//for Opening Loop line scrolling
} public
void DrawText (int nindex,canvas Canvas) {
hackline hackline = Mhacklines.get (nindex);
for (int i = 0; i < hackLine.hcs.size (); i++) {
Hackcode Hackcode = HackLine.hcs.get (i);
Mpaint.setalpha (Hackcode.alpha);
Canvas.drawtext (Hackcode.code, hackcode.p.x, HACKCODE.P.Y, mpaint);
}
The next step to scroll Handler
is to start by sending a message with a delay of 100 milliseconds:
Class Weakhandler extends handler{
weakreference<activity> mactivity;
public Weakhandler [activity activity] {
mactivity = new weakreference<activity> (activity);
}
@Override public
void handlemessage (Message msg) {
if (mactivity.get ()!= null) {
switch (msg.what) {
Case WHAT:
nextplay (dip2px (GetContext ());
for (int i = 0; i < mhacklines.size (); i++) {
if (mhacklines.get (i). P.y >= mheight/2*3) {
addhackline (mhack Lines.get (i));
}
Invalidate ();
Break;}}}
Let the whole line go down in fact, it is only by increasing the initial y-coordinate of the bottom of the line, the internal letters will update the position:
/**
* Next Frame play
* @param nnum each Move down how long distance
/public
void Nextplay (int nnum) {for
(int i = 0; i < Mhacklin Es.size (); i++) {
list
Then we have to consider removing unwanted lines of letters at the right time and adding new ones, and here I'm judging if the bottom of the line exceeds half the height of the screen, remove the current line and add a new line based on the unique label:
/**
* Delete a column add initialization column
* @param hackline
/public void Addhackline (Hackline hackline) {
if hackline = = null) {return
;
}
int num = hackline.num;
Mhacklines.remove (hackline);//If there is deletion
hackline hl again
; Hl= new Hackline ();
hl.p.x = mwidth/9* (num-1);
HL.P.Y = mheight/12* (7-(num-1));
for (int j = 0; J < 7; J +) {
Hackcode HC = new Hackcode ();
Hc.alpha-= 30*j;
Hc.code = Codes[new Random (). Nextint (Codes.length)];
hc.p.x = hl.p.x;
HC.P.Y = hl.p.y-dip2px (GetContext (), *j);
Hl.hcs.add (hc);
}
hl. num = num;
Mhacklines.add (HL);
}
Finally, when the control removes the screen, it terminates the message loop, and the runtime remembers to set the root layout to a black background:
@Override
protected void Ondetachedfromwindow () {
super.ondetachedfromwindow ();
Mhandler.removecallbacksandmessages (null);//Stop refreshing
}
Okok, the alphabet has come out of the rain ~ ~ After the clear thinking is still very simple oh ~
Second, the implementation of the Code
The entire code is not very long, it is directly attached:
/** * * Letter Rain * @author Zhang * * * * * * public class Hackview extends View {/** text brush * * Private Paint mpaint;
/** control's wide/private int mwidth;
/** control's high/private int mheight; /** all letters */private static final string[] codes = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"
, "P", "Q", "R", "S", "T", "U", "V", "W", "K", "Y", "Z"};
private static final int WHAT = 1;
/** All hackline combination * * Private list
Xml:
<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android"
xmlns:tools= "http:// Schemas.android.com/tools "
android:layout_width=" match_parent "
android:layout_height=" Match_parent "
android:background= "#000"
tools:context= ". Mainactivity ">
<com.zk.hack.hackview
android:layout_width=" match_parent "
android:layout_ height= "Match_parent"
/>
</RelativeLayout>
The above is based on Android to achieve the letter rain effect of all content, the effect is very good, the need for small partners can refer to learning.