Android TransitionDrawable 不褪色

Android TransitionDrawable not fading

我有一个 ImageView,我正在尝试使用以下代码从一张图片淡入到下一张图片:

Drawable bgs[] = new Drawable[2];
public void redraw(int[][] grid) {
    bgs[0] = bgs[1];
    bgs[1] = new GameDrawable(grid, prefs.colors);
    if (bgs[0] == null) {
        gameField.setImageDrawable(bgs[1]);
    } else {
        TransitionDrawable crossfader = new TransitionDrawable(bgs);
        crossfader.setCrossFadeEnabled(true);
        gameField.setImageDrawable(crossfader);
        crossfader.startTransition(500);
    }
}

gameField 被正确引用为 ImageView。

gameDrawable 只是扩展 Drawable 并绘制网格。

新 GameDrawable 的每一次移动和动作都被正确渲染,但没有任何褪色。新图像会立即显示出来。我试过延长过渡时间并交换可绘制对象的顺序,但没有效果。

感谢任何帮助。

更新:我现在已经将我的过渡设置为像 500000 这样长得离谱的东西。第一个可绘制对象显示几秒钟,然后突然出现第二个可绘制对象。所以仍然没有过渡。

更新 2: 我认为我的 Drawable 可能实现不正确,所以我附上了代码。

public class GameDrawable extends Drawable {

    private Paint paint = new Paint();
    private float blockWidth = 1;
    private int[][] myGrid;
    private int myColor;
    private List<Point> myPoints;

    public GameDrawable(int[][] grid) {
        super();
        this.myGrid = grid;
        this.myColor = colors[yourColor];
        paint.setStrokeWidth(1);
        paint.setStyle(Paint.Style.FILL);
        paint.setAlpha(0);
        this.myPoints = yourPoints;
    }

    @Override
    public void draw(Canvas canvas) {
        float height = getBounds().height();
        float width = getBounds().width();
        blockWidth = width / myGrid.length;
        if (height / myGrid.length < blockWidth) {
            blockWidth = height / myGrid.length;
        }

        for (int x = 0; x < myGrid.length; x++) {
            for (int y = 0; y < myGrid[x].length; y++) {
                paint.setColor(colors[myGrid[x][y]]);
                canvas.drawRect(x * blockWidth, y * blockWidth, (x+1)*blockWidth, (y+1)*blockWidth, paint);
            }
        }
    }

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

    @Override
    public void setColorFilter(ColorFilter cf) {
        paint.setColorFilter(cf);
        invalidateSelf();
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }
}

查看您的代码,我发现该行有问题

bgs[0] = bgs[1];

bgs[1] 尚未在此行之前定义,因此 bgs[0] 是第一个方法调用的 null。正因为如此,(bgs[0] == null)为真,所以后面定义的bgs[1]直接设置为gameField ImageView.

使用下面更正的代码。

Drawable bgs[] = new Drawable[2];
Drawable firstDrawable = getResources().getDrawable(R.drawable.transparent);

public void redraw(int[][] grid) {
    bgs[0] = firstDrawable;
    bgs[1] = new GameDrawable(grid, prefs.colors);
    firstDrawable = bgs[1];
    TransitionDrawable crossfader = new TransitionDrawable(bgs);
    crossfader.setCrossFadeEnabled(true);
    gameField.setImageDrawable(crossfader);
    crossfader.startTransition(500);
}

请注意,当 Drawable 大小不同时,TransitionDrawable 无法正常工作。所以你可能需要事先调整 firstDrawable 的大小。

EXTRA:我会避免 setCrossFadeEnabled(true) 因为整个 TransitionDrawable 在过渡期间变得半透明,露出背景。有时,这会产生 "blinking" 效果并破坏过渡的平滑度。

编辑:查看您的自定义 Drawable 实现,我认为问题在于行

canvas.drawColor(Color.WHITE);

在 draw() 方法中。

我查看了 TransitionDrawable.java 源代码,发现在可绘制对象上调用了 setAlpha 以获得淡入淡出效果。但是,您的 canvas 具有纯白色,而 setAlpha() 仅影响绘画。希望这是你的答案。

编辑 2:正如 Michael 所指出的,实际问题是 TransitionDrawable 对 Drawable 的 setAlpha() 调用因 GameDrawable 中的 paint.setColor() 而变得无效 draw() 方法覆盖由 TransitionDrawable 设置的绘制的 alpha 值。