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 值。
我有一个 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 值。