我正在试着用圆点组成的同心圆做一个自定义视图。我附上了一张截图作为参考。直到时间自定义视图只有同心圆,它工作良好,但一旦我应用dashpatheffect,它使整个屏幕缓慢,这是非常可观的时候,你试图打开或关闭导航抽屉。我已附上以下日志。
这是解释这个问题的视频链接
https://youtu.be/5Mgz4QhXaQI
自定义视图
public class ConcentricCircularView extends View {
private static final String TAG = "ConcentricCircularView";
private Paint paint;
private Context context;
public ConcentricCircularView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(Utils.dipToPixels(context,getResources().getDimension(R.dimen.d1)));
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setAntiAlias(true);
this.context=context;
}
int onDrawCounter = 0;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.e(TAG, "Actual radius"+getWidth());
int radius= (int) (getWidth()/3);
int distanceBtwDots= (int) Utils.dipToPixels(context,getResources().getDimension(R.dimen.d10));
Log.e(TAG, "Counter: "+onDrawCounter++);
for (int i=0;i<10;i++){
DashPathEffect dashPath = new DashPathEffect(new float[]{1,distanceBtwDots}, 0);
paint.setPathEffect(dashPath);
// Log.e(TAG, "Current radius "+radius);
canvas.drawCircle(getWidth()/2, getHeight()/2,radius, paint);
radius= (int) (radius+Utils.dipToPixels(context,getResources().getDimension(R.dimen.d15)));
distanceBtwDots= (int) (distanceBtwDots+Utils.dipToPixels(context,getResources().getDimension(R.dimen.d1)));
}
}
}
来自控制台的日志
[![03-22 12:01:38.734 19919-19919/com.lief.smartwallet D/ViewRootImpl: ViewPostImeInputStage processPointer 0
03-22 12:01:38.834 19919-19919/com.lief.smartwallet D/ViewRootImpl: ViewPostImeInputStage processPointer 1
03-22 12:01:39.474 19919-19919/com.lief.smartwallet I/Choreographer: Skipped 34 frames! The application may be doing too much work on its main thread.
03-22 12:01:43.184 19919-19919/com.lief.smartwallet I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@e65187c time:662629
03-22 12:01:47.559 19919-19919/com.lief.smartwallet D/ViewRootImpl: ViewPostImeInputStage processPointer 0
03-22 12:01:47.679 19919-19919/com.lief.smartwallet D/ViewRootImpl: ViewPostImeInputStage processPointer 1
最佳答案
你只需要保持一个boolean
来表示你是否需要画一些东西。目前,您不必要地在每次迭代中绘制完全相同的东西。
如Romain Guy所述:
一般来说,硬件层应该设置在绘制成本高、内容不会经常更改的视图上。
public class ConcentricCircularView extends View {
...
private boolean shouldDraw = true;
...
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (shouldDraw) {
shouldDraw = false;
setLayerType(View.LAYER_TYPE_HARDWARE, null);
// draw your view here
}
}
public void setShouldDraw(boolean shouldDraw) {
this.shouldDraw = shouldDraw;
}
}