2013-02-24 1 views
1

안드로이드 애니메이션 클래스를 살펴 봤지만 찾고있는 것이 무엇인지 잘 모르겠습니다. LayerDrawable의 단일 레이어에 애니메이션 변환 (X 좌표 변경)을 추가 할 수 있는지 궁금합니다. TranslateAnimation 클래스를 찾았지만 전체 ImageView에서만 작동하며 내 LayerDrawable의 단일 레이어에 애니메이션을 적용하려고합니다. 어떤 충고? 미리 감사드립니다.android : LayerDrawable의 단일 레이어를 애니메이션으로 변환하는 방법

답변

0

내 대답을 알아 냈습니다 ... 일단 LayerDrawable이 구성되면 실제로 레이어를 조작 할 수없는 것 같습니다. 응답이 없기 때문에 내 질문에 잘못된 것을 묻는 것 같아서 LayerDrawable을 사용하도록 다시 디자인했지만 각 애니메이션 앞뒤에 생성 및 파기되는 개별 drawable/imageView 개체로 애니메이션을 만들었습니다. 그런 다음 imageView에서 ObjectAnimator를 사용하여 원하는 이미지 변환을 얻습니다. 따라서 누구나 LayerDrawable의 개별 레이어에 애니메이션을 적용하려는이 읽는 경우, 다시 디자인하여 Animator 클래스를 사용할 수 있습니다. 하나는 구체적으로 그 당김

의 경계를 조정하기 위해 ValueAnimator를 사용할 수 있습니다 :

2

짧은 당신이 내부 항목 드로어 블 (id:innerRed)와 레이어 목록 드로어 블을 가지고 가정 하고, 레이아웃에 Button (id:btnWithDrawableBg)이 있고이 레이어 드로우 어블을 background 속성에 할당했다고 가정하면 ValueAnimator을 사용하여 아래 예와 같이 해당 드로어 블의 경계를 조정할 수 있습니다 (x 위치를 각각 100 씩 핑퐁합니다). 측면) :

pos_animator.xml

<?xml version="1.0" encoding="utf-8"?> 
<animator xmlns:andoird="http://schemas.android.com/apk/res/android" 
    andoird:repeatCount="infinite" 
    andoird:repeatMode="reverse" 
    andoird:valueFrom="-100" 
    andoird:valueTo="100" 
    andoird:valueType="intType" 
/> 

MyActivity.java

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    // our button with the drawable background 
    Button btnWithBg = (Button) findViewById(R.id.btnWithDrawableBg); 
    // the layered drawable 
    final LayerDrawable layerDrawable = (LayerDrawable) btnWithBg.getBackground(); 
    // internal layer (item) drawable with id:innerRed 
    final GradientDrawable innerRedShape = (GradientDrawable)layerDrawable.findDrawableByLayerId(R.id.innerRed); 
    // our animator based on the xml above 
    ValueAnimator posAnim = (ValueAnimator) AnimatorInflater.loadAnimator(
      mainLayout.getContext(), R.animator.pos_animator); 

    posAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
     @Override 
     public void onAnimationUpdate(ValueAnimator animation) { 
      // get current offset value and adjust drawable bounds 
      int value = (Integer)animation.getAnimatedValue(); 
      Rect bounds = innerRedShape.copyBounds();//see Note below 
      // here only manipulating x value 
      bounds.offset(value, 0); 
      innerRedShape.setBounds(bounds); 
     } 
    }); 
    posAnim.setTarget(innerRedShape); 
    posAnim.start(); 
} 

참고copyBounds()가 필요 (단지 getBounds().offset() 생략)이 SO post

0

에 기초 나는

에서 onCreate()

ImageView imageView = (ImageView) findViewById(R.id.imageView); 

Resources r = getResources(); 

Drawable[] layers = new Drawable[2]; 

layers[0] = r.getDrawable(R.drawable.your_background_res); 

PulseDrawable pulseDrawable = new PulseDrawable(Color.WHITE); 
layers[1] = pulseDrawable; 

LayerDrawable layerDrawable = new LayerDrawable(layers); 

// This will adjust X & Y of layer, we have to pass layer index (250 pixels from Left and 150 pixels from Right) 
layerDrawable.setLayerInset(1, 250, 150, 0, 0); 

imageView.setImageDrawable(layerDrawable); 

PulseDrawable.java

import android.animation.AnimatorSet; 
import android.animation.ValueAnimator; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.ColorFilter; 
import android.graphics.Paint; 
import android.graphics.RadialGradient; 
import android.graphics.Rect; 
import android.graphics.Shader; 
import android.graphics.drawable.Drawable; 
import android.view.animation.DecelerateInterpolator; 

public class PulseDrawable extends Drawable { 
    private final static float CENTER_AREA_SIZE = 0.6f; 
    private final static int PULSE_START_COLOR_OPACITY = 0; 
    private final static float MINIMUM_RADIUS = 0; 
    private final static int ANIMATION_DURATION_IN_MS = 1500; 
    private final int color; 
    private Paint centerPaint; 
    private Paint pulsePaint; 
    private float fullSizeRadius = 60; 
    private float currentExpandAnimationValue = 0f; 
    private int currentAlphaAnimationValue = 255; 

    public PulseDrawable(int color) { 
     this.color = color; 
     initializeDrawable(); 
    } 

    private void initializeDrawable() { 
     preparePaints(); 
     prepareAnimation(); 
    } 

    private void prepareAnimation() { 
     final ValueAnimator expandAnimator = ValueAnimator.ofFloat(0f, 1f); 
     expandAnimator.setRepeatCount(ValueAnimator.INFINITE); 
     expandAnimator.setRepeatMode(ValueAnimator.RESTART); 
     expandAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
      @Override 
      public void onAnimationUpdate(ValueAnimator animation) { 
       currentExpandAnimationValue = (float) animation.getAnimatedValue(); 
       if (currentExpandAnimationValue == 0f) { 
        currentAlphaAnimationValue = 255; 
       } 
       invalidateSelf(); 
      } 
     }); 
     final ValueAnimator alphaAnimator = ValueAnimator.ofInt(255, 0); 
     alphaAnimator.setStartDelay(ANIMATION_DURATION_IN_MS/4); 
     alphaAnimator.setRepeatCount(ValueAnimator.INFINITE); 
     alphaAnimator.setRepeatMode(ValueAnimator.RESTART); 
     alphaAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
      @Override 
      public void onAnimationUpdate(ValueAnimator animation) { 
       currentAlphaAnimationValue = (int) animation.getAnimatedValue(); 
      } 
     }); 
     AnimatorSet animation = new AnimatorSet(); 
     animation.playTogether(expandAnimator, alphaAnimator); 
     animation.setDuration(ANIMATION_DURATION_IN_MS); 
     animation.setInterpolator(new DecelerateInterpolator()); 
     animation.start(); 
    } 

    private void preparePaints() { 
     pulsePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     pulsePaint.setStyle(Paint.Style.FILL); 
     centerPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     centerPaint.setStyle(Paint.Style.FILL); 
     centerPaint.setColor(color); 
    } 

    @Override 
    public void setAlpha(int alpha) { 
     pulsePaint.setAlpha(alpha); 
    } 

    @Override 
    public void setColorFilter(ColorFilter colorFilter) { } 

    @Override 
    public int getOpacity() { 
     return pulsePaint.getAlpha(); 
    } 

    @Override 
    public void draw(Canvas canvas) { 
     Rect bounds = getBounds(); 

     //TODO - If we want to draw circle on center of canvas use below code 

     /*float centerX = bounds.exactCenterX(); 
     float centerY = bounds.exactCenterY();*/ 

     float startX = bounds.left; 
     float startY = bounds.top; 

//  calculateFullSizeRadius(); 
     preparePaintShader(); 
     renderPulse(canvas, startX, startY); 
     renderCenterArea(canvas, startX, startY); 
    } 

    private void renderPulse(Canvas canvas, float centerX, float centerY) { 
     float currentRadius = fullSizeRadius * currentExpandAnimationValue; 
     if (currentRadius > MINIMUM_RADIUS) { 
      canvas.drawCircle(centerX, centerY, currentRadius, pulsePaint); 
     } 
    } 

    private void renderCenterArea(Canvas canvas, float centerX, float centerY) { 
     float currentCenterAreaRadius = fullSizeRadius * CENTER_AREA_SIZE; 
     if (currentCenterAreaRadius > MINIMUM_RADIUS) { 
      canvas.save(); 
      float left = centerX - currentCenterAreaRadius; 
      float top = centerY - currentCenterAreaRadius; 
      float right = centerX + currentCenterAreaRadius; 
      float bottom = centerY + currentCenterAreaRadius; 
      canvas.clipRect(left, top, right, bottom); 
      canvas.drawCircle(centerX, centerY, currentCenterAreaRadius, centerPaint); 
      canvas.restore(); 
     } 
    } 
    private void preparePaintShader() { 
     Rect bounds = getBounds(); 
     float centerX = bounds.exactCenterX(); 
     float centerY = bounds.exactCenterY(); 
     float radius = (Math.min(bounds.width(), bounds.height())/2); 
     if (radius > MINIMUM_RADIUS) { 
      int edgeColor = getPulseColor(); 
      int centerColor = Color.argb(PULSE_START_COLOR_OPACITY, Color.red(color), 
        Color.green(color), 
        Color.blue(color)); 
      pulsePaint.setShader(new RadialGradient(centerX, centerY, radius, 
        centerColor, edgeColor, Shader.TileMode.CLAMP)); 
     } else { 
      pulsePaint.setShader(null); 
     } 
    } 

    private int getPulseColor() { 
     return Color.argb(currentAlphaAnimationValue, Color.red(color), 
       Color.green(color), 
       Color.blue(color)); 
    } 

    private void calculateFullSizeRadius() { 
     Rect bounds = getBounds(); 
     float minimumDiameter = Math.min(bounds.width(), bounds.height()); 
     fullSizeRadius = (minimumDiameter/2); 
    } 
} 

출력

enter image description here

: 수행이 방법 집결지 0

참고 : 데모 용으로 여러 레이어를 추가 할 수 있습니다. 두 레이어를 추가했습니다.

희망이 도움이 될 것입니다.

관련 문제