我已經看過了android動畫類,但我不確定我看到了我在找什麼。我想知道是否可以將翻譯動畫(更改X座標)添加到LayerDrawable的單個圖層?我找到了TranslateAnimation類,但它似乎只適用於整個ImageView,而我只想爲我的LayerDrawable的單一層設置動畫效果。有什麼建議?提前致謝。android:如何動畫翻譯一層LayerDrawable
1
A
回答
0
我已經想通了我的答案......看起來,一旦一個LayerDrawable組成,你真的不能操縱這些圖層。從缺乏反應,我認爲我的問題可能是要求錯誤的事情,我重新設計使用LayerDrawable,但動畫作爲單獨的drawable/imageView對象,我在每個動畫之前和之後生成和銷燬。然後,我使用imageView上的ObjectAnimator來實現圖像的所需翻譯。所以爲了防止任何人讀這個想要動畫他們的LayerDrawable的單個圖層,嘗試重新設計,以便您可以使用Animator類。
2
在短:可以使用一個ValueAnimator調整該繪製
邊界更詳細地說: 假設你有一個層列表可繪製的,具有內項繪製(id:innerRed
),和假設您的佈局中有Button
(id: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);
}
}
輸出
注意:您可以添加多個圖層,對於演示我添加了兩個圖層。
希望這會幫助你。
相關問題
- 1. Android翻譯動畫
- 2. 翻譯動畫
- 3. Android動畫。兩個翻譯活動
- 4. SVG動畫翻譯
- 5. 在Android代碼中的動畫翻譯
- 6. flickering在Android中翻譯動畫
- 7. Android翻譯動畫導致Clicklistener問題
- 8. 在Android中翻譯動畫問題
- 9. android frame-by-frame動畫和翻譯
- 10. Android的翻譯動畫進度回調
- 11. Android動畫 - 翻譯視圖組,兒童不從同一地點翻譯
- 12. 翻譯CSS動畫WPF動畫
- 13. 如何爲android製作曲線翻譯動畫?
- 14. ImageView scale +翻譯動畫
- 15. 翻譯動畫無效
- 16. 翻譯動畫代碼
- 17. 縮放和翻譯動畫
- 18. 在Firefox中翻譯動畫
- 19. Nativescript無限翻譯動畫
- 20. UIVIew動畫 - 縮放+翻譯
- 21. 翻譯和縮放動畫
- 22. 如何添加旋轉動畫來翻譯動畫?
- 23. Android:翻譯動畫第一次工作,而不是第二次
- 24. 多層android動畫
- 25. Android LayerDrawable:如何以編程方式設置圖層座標?
- 26. 移動videoView ...使用翻譯動畫
- 27. Android如何翻譯組名?
- 28. 在Android中翻頁/翻轉動畫?
- 29. 在翻譯動畫期間OnTouchListener不翻譯
- 30. Android ImageView翻轉動畫