간단 한 Android 궤적 애니메이션

본 논문 의 사례 는 안 드 로 이 드 궤적 애니메이션 의 구체 적 인 코드 를 공유 하여 여러분 께 참고 하 실 수 있 습 니 다.구체 적 인 내용 은 다음 과 같 습 니 다.
2.수요 설명
년 중 그때 기우 의 회 사 는 그 에 게 곡선 만 있 는 그림 을 주 었 다.그 에 게 곡선의 궤적 에 따라 전체 곡선 을 보 여 주 려 고 했 지만 기 우 는 여동생,만두 의 대가 로 나 를 매수 하 느 라 바 빠 서 코드 를 써 주 었 다.일단 실현 효 과 를 볼 게 요.                    

위의 원시 그림(원시 그림 의 궤적 곡선 은 흰색 이 고 다른 부분 은 투명 하 다.여 기 는 관찰 하기 편리 하도록 배경 을 검은색 으로 바 꾸 었 다)

3.분석 실현
        이 그림 을 처음 받 았 을 때 저도 어 리 석 었 습 니 다.불규칙 한 곡선 은 간단 한 방정식 을 통 해 구체 적 인 위 치 를 묘사 하지 못 한 것 이 분명 합 니 다.심지어 디자인 이 애니메이션 에 직접 주 는 것 이 좋 지 않 겠 습 니까? 
        홈 은 홈 으로 돌아 가 고 수 요 는 실현 해 야 한다.그리고 이 수 요 는 흔히 볼 수 있 는 방법 으로 이 루어 질 수 있다.예 를 들 어 상하 두 층 의 그림 을 계속 유지 하고 상층 부 는 왼쪽 에서 오른쪽으로 원 도 를 세로 로 픽 셀 로 제거 한 다음 에 디자인 된 그림 도 왼쪽 에서 친구 의 순 에 따라 그 릴 수 있다.그러나 이런 방법의 확장 성 이 너무 떨 어 지기 때문에 밑바닥 의 그림 이 바 뀌 고(미끄럼,변색)상층 도 협조 해 야 한다.
        그림 의 유색 픽 셀 을 그림 의 위치 에 비례 하여 그 릴 View 에 비 추 는 방법 입 니 다.
        예 를 들 어 원 그림 의 크기 는 200*100 이 고 보 여 주 려 는 View 의 크기 는 450*300 이 며 특정한 점 은 원 그림 에서 x100,y20 의 위치 에 있 으 면 view 에서 의 위 치 는 225,60 이 어야 한다.즉,이 점 이 도중에 있 는 위 치 를 원 그림 에 대응 하 는 사이즈 에 비교 한 다음 에 View 의 사 이 즈 를 곱 하면 된다.
        궤적 획득 은 모든 픽 셀 점 색상 을 획득 할 수 있 습 니 다.투명 한 것 은 반드시 궤적 이 아니 기 때문에 알파 값 을 판단 하면 됩 니 다.또한 궤적 은 하나의 선 이기 때문에 우리 가 Path 연결 점 을 사용 할 때 불필요 한 점 의 연결 을 최소 화하 기 위해 저 는 평균 값 으로 곡선의 너 비 를 1 로 낮 춥 니 다.
        점 의 위 치 는 사이즈 비례 에 따라 계산 되 기 때문에 보 여 드릴 그림 의 사이즈 가 아무리 기이 하 더 라 도 완벽 하 게 어 울 릴 수 있 습 니 다.        
실현 코드

public class TestView extends View implements ViewTreeObserver.OnGlobalLayoutListener{
 private Paint paint = new Paint();
 private Bitmap bitmap;
 private int[]local;
 boolean enter = false;
 int count;
 ViewTreeObserver observer;
 Canvas canvas;
 float lastX = 0;
 float lastY = 0;
 
 public TestView(Context context) {
  super(context);
 }
 
 public TestView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  observer = this.getViewTreeObserver();
  observer.addOnGlobalLayoutListener(this);
  getImageFromAssetsFile("target.png");//    
 }
 
 public TestView(Context context, AttributeSet attrs) {
  super(context, attrs);
  observer = this.getViewTreeObserver();
  observer.addOnGlobalLayoutListener(this);
  getImageFromAssetsFile("target.png");
 }
 
 private void getImageFromAssetsFile(String fileName) {
  AssetManager am = getResources().getAssets();
  try {
   InputStream is = am.open(fileName);
   bitmap = BitmapFactory.decodeStream(is);
   is.close();
  }
  catch (IOException e) {
   e.printStackTrace();
  }
 }
 
 
 private void filterColor(){
  int w = bitmap.getWidth();
  int h = bitmap.getHeight();
  int[]pixels = new int[w*h];
  local = new int[w];//       ,      Y     
  bitmap.getPixels(pixels,0,bitmap.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight());
  for(int i = 0; i < w; i++){
   int lenght = 0;
   int total = 0;
   for(int j = 0;j<h;j++){
     if (bitmap.getPixel(i, j) !=0) {
      lenght++;
      total+=j;
     }
   }
 
   System.out.println(lenght+"");
   if(lenght<15||((float)i/(float) w)<0.85)
    local[i] = total/lenght;
   else
     break;
  }
 }
 
 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  if(enter) {
   paint.setAntiAlias(true);      //        
   paint.setColor(Color.WHITE);     //      
   canvas.drawColor(Color.TRANSPARENT);     //    
   paint.setStrokeWidth((float) 6.0);    //  
   paint.setStyle(Paint.Style.STROKE);
 
   Path path = new Path();
   path.moveTo(0, (((float) getMeasuredHeight()-25) / (float)bitmap.getHeight()) * (float) local[0]+7);
   if (count <= bitmap.getWidth()) {
    if(count<bitmap.getWidth())
     count++;
    for (int i = 1; i < count - 1; i++) {
     if(local[i]>0) {
      path.lineTo((getMeasuredWidth() / (float) bitmap.getWidth()) * (float) i, (((float) getMeasuredHeight()-25) / (float) bitmap.getHeight()) * (float) local[i]+7);
      lastX = (getMeasuredWidth() / (float) bitmap.getWidth()) * (float) i;
      lastY = (((float) getMeasuredHeight()-25 )/ (float) bitmap.getHeight()) * (float) local[i];
     }
    }
   }
   if(count<bitmap.getWidth())
    postInvalidate();
   else {
    count = 0;
    postInvalidate();
   }
    canvas.drawPath(path, paint);
    paint.setStyle(Paint.Style.FILL);
    canvas.drawCircle(lastX, lastY+7, 7, paint);
//   }
  }else{
   this.canvas = canvas;
  }
 }
 
 @Override
 public void onGlobalLayout() {
  filterColor();
  enter = true;
  postInvalidate();
 }
}
물론 이 코드 도 기 우 를 교차 시 키 는 데 만 사 용 될 뿐 최적화 할 수 있 는 부분 이 적지 않다.예 를 들 어 그림 을 읽 어서 서브 스 레 드 에 놓 고 그림 의 크기 를 판단 하여 OOM,큰 그림 으로 그림 을 압축 하지 않도록 한다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기