안 드 로 이 드 애니메이션 레이더 스캐닝 효과
자,이해 하기 편리 하도록 애니메이션 이 보 는 내용 에 따라 순서대로 전개 하 겠 습 니 다.
준비 하 다.
이 간단 한 애니메이션 컨트롤 을 canvas(캔버스)와 paint(붓)로 구현 하기 로 했 습 니 다.
그림 에서 두 개의 교차 하 는 십자선,몇 개의 동그라미 와 흰 점 을 볼 수 있다.그러면 먼저 필요 한 붓,캔버스 와 데 이 터 를 정의 한다.
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);
여기 스 위 프 그 라 디 언 트.SweetGradient 의 구조 함수:
public SweepGradient(float cx, float cy, int[] colors, float[] positions)
public SweepGradient(float cx, float cy, int color0, int color1)
그 중에서 cx,cy 는 원심,color 1,color 0 또는 colors 는 그 라 데 이 션 색상 을 지정 합 니 다.두 가지 이상 의 색상 을 사용 할 때 positions 를 통 해 각 색상 의 상대 적 인 위 치 를 지정 할 수 있 습 니 다.positions 는 NULL 로 설정 할 때 색상 의 균일 한 분 포 를 표시 합 니 다.기본 도형 그리 기
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);
이렇게 해서 전체 UI 를 제외 하고 애니메이션 을 추가 하면 전체적인 효 과 를 실현 할 수 있 습 니 다.애니메이션 구현
여기 서 애니메이션 을 실현 할 때 Matrix 라 는 것,즉 행렬 을 사용 했다.학교 에 다 닐 때 선형 대수 선생님 께 서 각종 선형 변 화 를 말씀 하 셨 을 때 머 릿 속 에 생각 했 습 니 다.이 물건 이 왜 만 났 는 지 지금 은 만 났 습 니 다.지금도 구름 속 에 안개 속 에 있 는 것 같 습 니 다.전체적으로 말 하면 Matrix 를 사용 하여 강력 한 그래 픽 애니메이션 을 실현 할 수 있 습 니 다.변위,회전,확대 와 투명 변화 등 효 과 를 포함 하고 matrix 는 일련의 setTranslate,setRotate,setScale 등 방법 을 가지 고 있 습 니 다.도형 의 각종 변 화 를 편리 하 게 실현 하려 면 주로 각종 변 화 를 이해 해 야 한다.
애니메이션 구현 스 레 드
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();
}
}
}
}
}
우선,여 기 는 독립 된 스 레 드 에서 start 를 계속 누적 하여 회전 각도 로 합 니 다.그리고 이 를 matrix 와 연결 합 니 다.matrix 의 세 가지 방법 을 사용 해 보 았 지만 차이 점 은 발견 되 지 않 았 습 니 다.애니메이션 그리 기
다음 에 onDraw 방법 에서 그림 을 계속 그리 면 됩 니 다.
// matrix , shader,
canvas.concat(matrix);
canvas.drawCircle(viewSize / 2, viewSize / 2, 350, mPaintSector);
최종 실현자,최종 전체 코드 는 다음 과 같 습 니 다.
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();
}
}
}
}
}
}
설명 하 다.나머지 부분 은 더 이상 설명 하지 않 고 코드 에 주석 이 잘 달 려 있 습 니 다.이 RadarView 의 사용 도 간단 합 니 다.멈 춰 야 할 때 stop 방법 을 사용 하면 됩 니 다.
@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();
}
여기 서 레이더 뷰 사 이 즈 는 800 으로 설정 되 어 있 기 때문에 레이아웃 파일 에 큰 시간 을 설정 하면 작 동 하지 않 습 니 다.정상적으로 사용 할 때 는 실제 수요 에 따라 view size 크기 와 몇 개의 Circle 의 반지름 을 조정 하여 더욱 좋 은 UI 디 스 플레이 효 과 를 얻 을 수 있 습 니 다.총결산
이상 은 안 드 로 이 드 에서 레이더 스캐닝 효과 가 실 현 된 모든 내용 입 니 다.본 고 는 안 드 로 이 드 개발 에 도움 이 되 기 를 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.