2013-02-24 99 views
1

我已經看過了android動畫類,但我不確定我看到了我在找什麼。我想知道是否可以將翻譯動畫(更改X座標)添加到LayerDrawable的單個圖層?我找到了TranslateAnimation類,但它似乎只適用於整個ImageView,而我只想爲我的LayerDrawable的單一層設置動畫效果。有什麼建議?提前致謝。android:如何動畫翻譯一層LayerDrawable

回答

0

我已經想通了我的答案......看起來,一旦一個LayerDrawable組成,你真的不能操縱這些圖層。從缺乏反應,我認爲我的問題可能是要求錯誤的事情,我重新設計使用LayerDrawable,但動畫作爲單獨的drawable/imageView對象,我在每個動畫之前和之後生成和銷燬。然後,我使用imageView上的ObjectAnimator來實現圖像的所需翻譯。所以爲了防止任何人讀這個想要動畫他們的LayerDrawable的單個圖層,嘗試重新設計,以便您可以使用Animator類。

2

在短:可以使用一個ValueAnimator調整該繪製

邊界更詳細地說: 假設你有一個層列表可繪製的,具有內項繪製(id:innerRed),和假設您的佈局中有Buttonid:btnWithDrawableBg),並且您已將此分層繪圖分配給background屬性,則可以使用ValueAnimator來調整該繪圖的邊界,如下面的示例(將每個x位置ping 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

我h AVE做到這樣:

的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

注意:您可以添加多個圖層,對於演示我添加了兩個圖層。

希望這會幫助你。