Heim  >  Artikel  >  Java  >  Radarscaneffekt für Android-Animationen

Radarscaneffekt für Android-Animationen

高洛峰
高洛峰Original
2017-01-16 17:18:172258Durchsuche

Schauen wir uns zunächst die Renderings an, um einen Gesamteindruck zu bekommen

Radarscaneffekt für Android-Animationen

Okay, um das Verständnis zu erleichtern, werden wir hier auf den Inhalt der Animation eingehen in Ordnung

Vorbereitung

Hier haben wir uns entschieden, Leinwand (Leinwand) und Farbe (Pinsel) zu verwenden, um diese einfache Animationssteuerung zu implementieren.

Wie Sie auf dem Bild sehen können, gibt es zwei gekreuzte Kreuzlinien, mehrere Kreise und einige weiße Punkte. Definieren Sie also zunächst den erforderlichen Pinsel, die Leinwand und einige Daten

setBackgroundColor(Color.TRANSPARENT);
 
 //宽度=5,抗锯齿,描边效果的白色画笔
 mPaintLine = new Paint();
 mPaintLine.setStrokeWidth(5);
 mPaintLine.setAntiAlias(true);
 mPaintLine.setStyle(Style.STROKE);
 mPaintLine.setColor(Color.WHITE);
 
 //宽度=5,抗锯齿,描边效果的浅绿色画笔
 mPaintCircle = new Paint();
 mPaintCircle.setStrokeWidth(5);
 mPaintCircle.setAntiAlias(true);
 mPaintCircle.setStyle(Style.FILL);
 mPaintCircle.setColor(0x99000000);
 
 //暗绿色的画笔
 mPaintSector = new Paint();
 mPaintSector.setColor(0x9D00ff00);
 mPaintSector.setAntiAlias(true);
 //定义一个暗绿色的梯度渲染
 mShader = new SweepGradient(viewSize / 2, viewSize / 2,
Color.TRANSPARENT, Color.GREEN);
 mPaintSector.setShader(mShader);
 
 //白色实心画笔
 mPaintPoint=new Paint();
 mPaintPoint.setColor(Color.WHITE);
 mPaintPoint.setStyle(Style.FILL);
 
 //随机生成一些数组点,模拟雷达扫描结果
 point_x = UtilTools.Getrandomarray(15, 300);
 point_y = UtilTools.Getrandomarray(15, 300);

Hier Sprechen Sie über den Konstruktor von SweepGradient

SweepGradient:

public SweepGradient(float cx, float cy, int[] colors, float[] positions)
public SweepGradient(float cx, float cy, int color0, int color1)

wobei cx, cy den Mittelpunkt des Kreises angibt, color1, color0 oder Colors die Farbe des Farbverlaufs angeben Verwendung mit mehr als zwei Farben. Bei der Auswahl von Farben können Sie auch die relative Position jeder Farbe über „Positionen“ angeben. Wenn „Positionen“ auf NULL gesetzt ist, bedeutet dies, dass die Farben gleichmäßig verteilt sind.

Grundlegende Grafiken zeichnen

canvas.drawCircle(viewSize / 2, viewSize / 2, 350, mPaintCircle);
canvas.drawCircle(viewSize / 2, viewSize / 2, 255, mPaintLine);
canvas.drawCircle(viewSize / 2, viewSize / 2, 125, mPaintLine);
canvas.drawCircle(viewSize / 2, viewSize / 2, 350, mPaintLine);
//绘制两条十字线
canvas.drawLine(viewSize / 2, 0, viewSize / 2, viewSize, mPaintLine);
canvas.drawLine(0, viewSize / 2, viewSize, viewSize / 2, mPaintLine);

Auf diese Weise wird die gesamte Benutzeroberfläche gezeichnet und anschließend eine Animation hinzugefügt, um den Gesamteffekt zu erzielen.

Animationsimplementierung

Bei der Implementierung von Animationen wird hier die Matrix verwendet, die die Matrix darstellt. Als ich in der Schule war, als der Lehrer für lineare Algebra über verschiedene lineare Transformationen sprach, dachte ich darüber nach, wofür dieses Ding gedacht ist. Jetzt bin ich endlich darauf gestoßen, und jetzt scheint es verwirrend zu sein. Im Allgemeinen können Sie mit Matrix leistungsstarke grafische Animationen erzielen, einschließlich Verschiebungs-, Rotations-, Skalierungs- und Transparenzänderungen. Matrix verfügt über eine Reihe von Methoden wie setTranslate, setRotate und setScale. Es ist sehr praktisch, verschiedene Transformationen von Grafiken zu realisieren. Die Hauptsache ist, verschiedene Transformationen zu verstehen.

Animationsimplementierungsthread

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();
       //设定旋转角度,制定进行转转操作的圆心
//       matrix.postRotate(start, viewSize / 2, viewSize / 2);
//       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();
     }
    }
   }
  }
 }

Zunächst wird der Start kontinuierlich in einem unabhängigen Thread als Drehwinkel akkumuliert. Dann verknüpfen Sie es mit der Matrix. Hier habe ich versucht, drei Matrixmethoden zu verwenden, aber vorerst wurde kein Unterschied festgestellt.

Animationszeichnung

Als nächstes fahren Sie mit dem Zeichnen von Grafiken in der onDraw-Methode fort

//根据matrix中设定角度,不断绘制shader,呈现出一种扇形扫描效果
canvas.concat(matrix);
canvas.drawCircle(viewSize / 2, viewSize / 2, 350, mPaintSector);

Endlich erreicht

Okay, das Der endgültige Gesamtcode lautet wie folgt:

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;
 //旋转效果起始角度
 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 {
 
 }
 //默认为顺时针呢
 private final static int DEFAULT_DIERCTION=CLOCK_WISE;
 
 //设定雷达扫描方向
 private int direction=DEFAULT_DIERCTION;
 
 private boolean threadRunning = true;
 
 public RadarView(Context context, AttributeSet attrs) {
  super(context, attrs);
  // TODO Auto-generated constructor stub
  mContext = context;
  initPaint();
 }
 
 public RadarView(Context context) {
  super(context);
  // TODO Auto-generated constructor stub
  mContext = context;
  initPaint();
 
 }
 
 private void initPaint() {
  // TODO Auto-generated method stub
  setBackgroundColor(Color.TRANSPARENT);
 
  //宽度=5,抗锯齿,描边效果的白色画笔
  mPaintLine = new Paint();
  mPaintLine.setStrokeWidth(5);
  mPaintLine.setAntiAlias(true);
  mPaintLine.setStyle(Style.STROKE);
  mPaintLine.setColor(Color.WHITE);
 
  //宽度=5,抗锯齿,描边效果的浅绿色画笔
  mPaintCircle = new Paint();
  mPaintCircle.setStrokeWidth(5);
  mPaintCircle.setAntiAlias(true);
  mPaintCircle.setStyle(Style.FILL);
  mPaintCircle.setColor(0x99000000);
 
  //暗绿色的画笔
  mPaintSector = new Paint();
  mPaintSector.setColor(0x9D00ff00);
  mPaintSector.setAntiAlias(true);
  mShader = new SweepGradient(viewSize / 2, viewSize / 2, Color.TRANSPARENT, Color.GREEN);
  mPaintSector.setShader(mShader);
 
  //白色实心画笔
  mPaintPoint=new Paint();
  mPaintPoint.setColor(Color.WHITE);
  mPaintPoint.setStyle(Style.FILL);
 
  //随机生成的点,模拟雷达扫描结果
  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 stub
  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, 350, mPaintCircle);
  canvas.drawCircle(viewSize / 2, viewSize / 2, 255, mPaintLine);
  canvas.drawCircle(viewSize / 2, viewSize / 2, 125, mPaintLine);
  canvas.drawCircle(viewSize / 2, viewSize / 2, 350, mPaintLine);
  //绘制两条十字线
  canvas.drawLine(viewSize / 2, 0, viewSize / 2, viewSize, mPaintLine);
  canvas.drawLine(0, viewSize / 2, viewSize, viewSize / 2, mPaintLine);
 
 
  //这里在雷达扫描过制定圆周度数后,将随机绘制一些白点,模拟搜索结果
  if (start > 100) {
   for (int i = 0; i < 2; i++) {
    canvas.drawCircle(viewSize / 2 + point_x[i], viewSize / 2 + point_y[i], 10, mPaintPoint);
   }
  }
  if (start > 200) {
   for (int i = 2; i < 5; i++) {
    canvas.drawCircle(viewSize / 2 + point_x[i], viewSize / 2 + point_y[i], 10, mPaintPoint);
   }
  }
  if (start > 300) {
   for (int i = 5; i < 9; i++) {
    canvas.drawCircle(viewSize / 2 + point_x[i], viewSize / 2 + point_y[i], 10, mPaintPoint);
   }
  }
  if (start > 500) {
   for (int i = 9; i < 11; i++) {
    canvas.drawCircle(viewSize / 2 + point_x[i], viewSize / 2 + point_y[i], 10, mPaintPoint);
   }
  }
  if (start > 800) {
   for (int i = 11; i < point_x.length; i++) {
    canvas.drawCircle(viewSize / 2 + point_x[i], viewSize / 2 + point_y[i], 10, mPaintPoint);
   }
  }
 
  //根据matrix中设定角度,不断绘制shader,呈现出一种扇形扫描效果
  canvas.concat(matrix);
  canvas.drawCircle(viewSize / 2, viewSize / 2, 350, mPaintSector);
  super.onDraw(canvas);
 }
 
 public void setDirection(@RADAR_DIRECTION int direction) {
  if (direction != CLOCK_WISE && direction != ANTI_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();
       //设定旋转角度,制定进行转转操作的圆心
//       matrix.postRotate(start, viewSize / 2, viewSize / 2);
//       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();
     }
    }
   }
  }
 }
}

Erklärung

Die redundanten Teile werden nicht erklärt, der Code wurde klar kommentiert. Die Verwendung dieses RadarView ist ebenfalls sehr einfach. Wenn Sie anhalten müssen, rufen Sie einfach die Stopp-Methode auf.

@Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  RadarView radarView = (RadarView) findViewById(R.id.radar);
  //设置雷达扫描方向
  radarView.setDirection(RadarView.ANTI_CLOCK_WISE);
  radarView.start();
 }

Hier ist die Radar-Ansichtsgröße auf 800 eingestellt, sodass das Festlegen der Größe in der Layoutdatei nicht funktioniert. Bei normaler Verwendung müssen die Ansichtsgröße und der Radius mehrerer Kreise entsprechend der tatsächlichen Größe angepasst werden muss einen besseren UI-Anzeigeeffekt erzielen.

Zusammenfassung

Das Obige ist der gesamte Inhalt des Radar-Scanning-Effekts in Android. Ich hoffe, dieser Artikel wird für alle in der Android-Entwicklung hilfreich sein.

Weitere Artikel zum Radarscaneffekt von Android-Animationen finden Sie auf der chinesischen PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn