Let's look at the effect chart first, and have an overall impression
Well, to make it easier to understand, here's what the animation sees in turn.
Get ready
Here it is decided to implement this simple animation control with canvas (canvas) and paint (brush).
With two crossed crosses, several circles, and some white dots, you can first define the brushes, canvas, and data that you want.
SetBackgroundColor (color.transparent);
width = 5, anti-aliasing, stroke effect white brush mpaintline = new Paint ();
Mpaintline.setstrokewidth (5);
Mpaintline.setantialias (TRUE);
Mpaintline.setstyle (Style.stroke);
Mpaintline.setcolor (Color.White);
width = 5, anti-aliasing, light green brush for stroke effect mpaintcircle = new Paint ();
Mpaintcircle.setstrokewidth (5);
Mpaintcircle.setantialias (TRUE);
Mpaintcircle.setstyle (Style.fill);
Mpaintcircle.setcolor (0x99000000);
Dark green Brush mpaintsector = new Paint ();
Mpaintsector.setcolor (0X9D00FF00);
Mpaintsector.setantialias (TRUE);
Defines a dark green gradient rendering Mshader = new Sweepgradient (VIEWSIZE/2, VIEWSIZE/2, Color.transparent, Color.green);
Mpaintsector.setshader (Mshader);
White Solid Brush mpaintpoint=new Paint ();
Mpaintpoint.setcolor (Color.White);
Mpaintpoint.setstyle (Style.fill);
Random generation of some array points, analog radar scan results point_x = Utiltools.getrandomarray (15, 300);
Point_y = Utiltools.getrandomarray (in);
Here's the sweepgradient.
The Sweepgradient constructor:
Public sweepgradient (float CX, float CY, int[] colors, float[] positions)
Public sweepgradient (float CX, float CY, int color0, int color1)
Where cx,cy specifies the center of a circle, color1,color0 or colors specifies the color of the gradient, and when more than two colors are used, the relative position of each color can be specified by positions, and the color is evenly distributed when the positions is set to NULL.
Draw Basic Graphics
Canvas.drawcircle (VIEWSIZE/2, VIEWSIZE/2, mpaintcircle);
Canvas.drawcircle (VIEWSIZE/2, VIEWSIZE/2, 255, mpaintline);
Canvas.drawcircle (VIEWSIZE/2, VIEWSIZE/2, mpaintline);
Canvas.drawcircle (VIEWSIZE/2, VIEWSIZE/2, mpaintline);
Draw two Cross line
Canvas.drawline (VIEWSIZE/2, 0, VIEWSIZE/2, viewsize, mpaintline);
Canvas.drawline (0, VIEWSIZE/2, viewsize, VIEWSIZE/2, mpaintline);
This will draw the entire UI, and then the animation, you can achieve the overall effect.
Animation implementation
When the animation is implemented here, the matrix is used. When I was at school, the linear algebra teacher was talking about all kinds of linear transformations, thinking in his head, what the hell this thing is doing, it's finally met, and now it seems foggy. In general, the matrix can be used to achieve powerful graphics animation, including displacement, rotation, scaling and transparent changes, the matrix has a series of Settranslate,setrotate,setscale and other methods. It is very convenient to realize various transformations of graphics, and it is important to understand various transformations.
Animation implementation Thread
Protected class Scanthread extends Thread {
private radarview view;
Public Scanthread (Radarview view) {
//TODO auto-generated constructor stub
this.view = view;
}
@Override public
Void Run () {
//TODO auto-generated method stub while
(Threadrunning) {
if (Isstart) { C11/>view.post (New Runnable () {public
void run () {
start = start + 1;
Matrix = new Matrix ();
Set the rotation angle, make the center
// matrix.postrotate (Start, VIEWSIZE/2, VIEWSIZE/2) for the rotary operation; matrix.setrotate (START,VIEWSIZE/2,VIEWSIZE/2);
Matrix.prerotate (DIRECTION*START,VIEWSIZE/2,VIEWSIZE/2);
View.invalidate ();
}
);
try {
thread.sleep (5);
} catch (Interruptedexception e) {
//TODO auto-generated catch
block E.printstacktrace ();}}}}
First, there is a constant accumulation of start in an independent thread, as a rotational angle. It is then associated with the matrix. Here we try to use the matrix's three methods, no difference is found for the time being.
Animation drawing
Next, you can continue drawing graphics in the OnDraw method
According to the setting angle of matrix, the shader is drawn continuously, showing a kind of fan-scan effect
canvas.concat (matrix);
Canvas.drawcircle (VIEWSIZE/2, VIEWSIZE/2, mpaintsector);
Final implementation
Well, the final overall code is as follows:
public class Radarview extends Framelayout {private context mcontext;
private int viewsize = 800;
Private Paint Mpaintline;
Private Paint mpaintcircle;
Private Paint Mpaintsector;
public Boolean isstart = false;
Private Scanthread Mthread;
Private Paint Mpaintpoint;
Rotation effect starting angle private int start = 0;
Private int[] point_x;
Private int[] point_y;
Private Shader Mshader;
Private matrix matrix;
Public final static int clock_wise=1;
Public final static int anti_clock_wise=-1; @IntDef ({clock_wise, anti_clock_wise}) public @interface radar_direction {}//default is clockwise private final static int DEF
Ault_dierction=clock_wise;
Set radar scanning direction private int direction=default_dierction;
Private Boolean threadrunning = true;
Public Radarview (context, AttributeSet attrs) {Super (context, attrs);
TODO auto-generated constructor stub mcontext = context;
Initpaint ();
Public Radarview {Super (context); TODO auto-generated Constructor stub mcontext = context;
Initpaint ();
private void Initpaint () {//TODO auto-generated Method Stub SetBackgroundColor (color.transparent);
width = 5, anti-aliasing, stroke effect white brush mpaintline = new Paint ();
Mpaintline.setstrokewidth (5);
Mpaintline.setantialias (TRUE);
Mpaintline.setstyle (Style.stroke);
Mpaintline.setcolor (Color.White);
width = 5, anti-aliasing, light green brush for stroke effect mpaintcircle = new Paint ();
Mpaintcircle.setstrokewidth (5);
Mpaintcircle.setantialias (TRUE);
Mpaintcircle.setstyle (Style.fill);
Mpaintcircle.setcolor (0x99000000);
Dark green Brush mpaintsector = new Paint ();
Mpaintsector.setcolor (0X9D00FF00);
Mpaintsector.setantialias (TRUE);
Mshader = new Sweepgradient (VIEWSIZE/2, VIEWSIZE/2, Color.transparent, Color.green);
Mpaintsector.setshader (Mshader);
White Solid Brush mpaintpoint=new Paint ();
Mpaintpoint.setcolor (Color.White);
Mpaintpoint.setstyle (Style.fill);
Randomly generated points, analogue radar scan results point_x = Utiltools.getrandomarray (15, 300); Point_y = Utiltools.getrandomarray(15, 300);
public void setviewsize (int size) {this.viewsize = size;
Setmeasureddimension (Viewsize, viewsize); @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {//TODO auto-generated method Stu
b setmeasureddimension (viewsize, viewsize);
public void Start () {mthread = new Scanthread (this);
Mthread.setname ("Radar");
Mthread.start ();
Threadrunning = true;
Isstart = true;
public void Stop () {if (Isstart) {threadrunning = false;
Isstart = false; } @Override protected void OnDraw (Canvas Canvas) {//TODO auto-generated Method stub canvas.drawcircle (viewsize
/2, VIEWSIZE/2, mpaintcircle);
Canvas.drawcircle (VIEWSIZE/2, VIEWSIZE/2, 255, mpaintline);
Canvas.drawcircle (VIEWSIZE/2, VIEWSIZE/2, mpaintline);
Canvas.drawcircle (VIEWSIZE/2, VIEWSIZE/2, mpaintline);
Draw two Cross line Canvas.drawline (VIEWSIZE/2, 0, VIEWSIZE/2, viewsize, mpaintline); Canvas.drawline (0, viewSIZE/2, Viewsize, VIEWSIZE/2, mpaintline); Here, after the radar has developed a circumference degree, will randomly draw some white dots, analog search results if (Start >) {for (int i = 0; i < 2; i++) {canvas.drawcircle
IZE/2 + point_x[i], VIEWSIZE/2 + point_y[i], mpaintpoint); } if (Start >) {for (int i = 2; i < 5; i++) {canvas.drawcircle (VIEWSIZE/2 + point_x[i], Viewsiz
E/2 + point_y[i], mpaintpoint); } if (Start >) {for (int i = 5; i < 9; i++) {canvas.drawcircle (VIEWSIZE/2 + point_x[i], Viewsiz
E/2 + point_y[i], mpaintpoint); } if (Start >) {for (int i = 9; i < i++) {canvas.drawcircle (VIEWSIZE/2 + point_x[i], viewsi
ZE/2 + point_y[i], mpaintpoint); } if (Start >) {for (int i = i < point_x.length i++) {canvas.drawcircle (VIEWSIZE/2 + point
_x[i], VIEWSIZE/2 + point_y[i], mpaintpoint);
}///According to the set angle of matrix, draw shader continuously, present a kind of fan-scan effect canvas.concat (matrix); Canvas.drawcircLe (VIEWSIZE/2, VIEWSIZE/2, mpaintsector);
Super.ondraw (canvas); public void setdirection (@RADAR_DIRECTION int DIRECTION) {if DIRECTION!= clock_wise && DIRECTION!=
Clock_wise) {throw new IllegalArgumentException ("Use @RADAR_DIRECTION constants only!");
} this.direction = direction;
} protected class Scanthread extends Thread {private Radarview view;
Public Scanthread (Radarview view) {//TODO auto-generated constructor stub this.view = view;
@Override public void Run () {//TODO auto-generated method stub while (threadrunning) {if (Isstart) {
View.post (New Runnable () {public void run () {start = start + 1;
Matrix = new Matrix ();
Set the rotation angle, make the Center//matrix.postrotate (Start, VIEWSIZE/2, VIEWSIZE/2) for the rotary operation;
Matrix.setrotate (START,VIEWSIZE/2,VIEWSIZE/2);
Matrix.prerotate (DIRECTION*START,VIEWSIZE/2,VIEWSIZE/2);
View.invalidate ();
}
}); try {thread.sleep (5);
catch (Interruptedexception e) {//TODO auto-generated catch block E.printstacktrace (); }
}
}
}
}
}
Description
The extra part is no longer explained and the code is clearly annotated. The use of this radarview is also very simple, you need to stop, call its Stop method.
@Override
protected void onCreate (Bundle savedinstancestate) {
super.oncreate (savedinstancestate);
Setcontentview (r.layout.activity_main);
Radarview Radarview = (radarview) Findviewbyid (R.id.radar);
Set radar scanning direction
radarview.setdirection (radarview.anti_clock_wise);
Radarview.start ();
}
Here the radar viewsize set to 800, so in the layout file size will not work, normal use, according to the actual need to adjust the viewsize size and a few circle radius, so as to achieve a better UI display effect.
Summarize
The above is the entire content that the radar scanning effect realizes in Android, hope this article is helpful to everybody Android development.