Android: 不擦除先前绘制的顺序绘制
Android: Sequential Drawing Without Erasing Previously Drawn
假设您想按顺序为路径列表设置动画。
我有一个可以存储路径列表的自定义视图,我重写了 onDraw 方法,这样我就可以 select 动画路径。我使用名为 currentPath 的索引来执行此操作。
var pathList = mutableListOf<Path>()
var currentPath = 0
public override fun onDraw(canvas: Canvas) {
if (!this.pathList.isEmpty()){
canvas.drawPath(this.pathList[this.currentPath], brushOutput)
}
}
我可以使用 属性 动画为路径设置动画。
为此,我有一个 class OnePath 封装了所有内容以动画化一条路径
class OnePath(val brush: Paint, val length: Float, val view: PaintView, val currentPath: Int): Path() {
val animator = ObjectAnimator.ofFloat(this, "phase", 1.0f, 0.0f)
fun setPhase(phase: Float) {
view.currentPath = currentPath // set the index of the path to draw in the view
brush.pathEffect = createPathEffect(length, phase, 1.0f) // animate model output
view.invalidate() /* will call onDraw */
}
private fun createPathEffect(pathLength: Float, phase: Float, offset: Float): PathEffect {
return DashPathEffect(
floatArrayOf(pathLength, pathLength),
Math.max(phase * pathLength, offset)
)
}
}
然后为了按顺序为路径列表设置动画,我使用了一个具有以下内容的 AnimatorSet
val animatorSet = AnimatorSet()
val listAnimator = mutableListOf<Animator>()
for (i in 0..len-1){
val path_i = OnePath(paint, lengthList[i], binding.paintView, i)
listAnimator.add(path_i.animator)
}
animatorSet.playSequentially(listAnimator)
animatorSet.setDuration(2000).start()
然而,这样做的结果是,每条路径都按顺序进行动画处理,但是每当绘制一条路径时,它就会在下一条路径被动画化时消失。
我想要的是在屏幕上保留每条动画路径。你会怎么做?
可以使用一对Bitmap
和Canvas
来缓存之前在PaintView
中绘制的路径:
private Canvas extraCanvas;
private Bitmap extraBitmap;
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if(extraBitmap != null && !extraBitmap.isRecycled()){
extraBitmap.recycle();
}
extraBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
extraCanvas = new Canvas(extraBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
if (!this.pathList.isEmpty()){
extraCanvas.drawPath(pathList.get(currentPath), brushOutput);
}
// Draw the bitmap that has all the saved paths:
canvas.drawBitmap(extraBitmap, 0f, 0f, null);
}
上的代码实验室
假设您想按顺序为路径列表设置动画。
我有一个可以存储路径列表的自定义视图,我重写了 onDraw 方法,这样我就可以 select 动画路径。我使用名为 currentPath 的索引来执行此操作。
var pathList = mutableListOf<Path>()
var currentPath = 0
public override fun onDraw(canvas: Canvas) {
if (!this.pathList.isEmpty()){
canvas.drawPath(this.pathList[this.currentPath], brushOutput)
}
}
我可以使用 属性 动画为路径设置动画。 为此,我有一个 class OnePath 封装了所有内容以动画化一条路径
class OnePath(val brush: Paint, val length: Float, val view: PaintView, val currentPath: Int): Path() {
val animator = ObjectAnimator.ofFloat(this, "phase", 1.0f, 0.0f)
fun setPhase(phase: Float) {
view.currentPath = currentPath // set the index of the path to draw in the view
brush.pathEffect = createPathEffect(length, phase, 1.0f) // animate model output
view.invalidate() /* will call onDraw */
}
private fun createPathEffect(pathLength: Float, phase: Float, offset: Float): PathEffect {
return DashPathEffect(
floatArrayOf(pathLength, pathLength),
Math.max(phase * pathLength, offset)
)
}
}
然后为了按顺序为路径列表设置动画,我使用了一个具有以下内容的 AnimatorSet
val animatorSet = AnimatorSet()
val listAnimator = mutableListOf<Animator>()
for (i in 0..len-1){
val path_i = OnePath(paint, lengthList[i], binding.paintView, i)
listAnimator.add(path_i.animator)
}
animatorSet.playSequentially(listAnimator)
animatorSet.setDuration(2000).start()
然而,这样做的结果是,每条路径都按顺序进行动画处理,但是每当绘制一条路径时,它就会在下一条路径被动画化时消失。
我想要的是在屏幕上保留每条动画路径。你会怎么做?
可以使用一对Bitmap
和Canvas
来缓存之前在PaintView
中绘制的路径:
private Canvas extraCanvas;
private Bitmap extraBitmap;
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if(extraBitmap != null && !extraBitmap.isRecycled()){
extraBitmap.recycle();
}
extraBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
extraCanvas = new Canvas(extraBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
if (!this.pathList.isEmpty()){
extraCanvas.drawPath(pathList.get(currentPath), brushOutput);
}
// Draw the bitmap that has all the saved paths:
canvas.drawBitmap(extraBitmap, 0f, 0f, null);
}
上的代码实验室