Hatching effect, making the screen lethargic

I am trying to create a custom view with concentric circles consisting of points. I applied the screenshot for reference. Until the user view has concentric circles, it works fine, but as soon as I apply DashPathEffect, it makes the whole screen sluggish, which is very well observed when trying to open or close the navigation box. I have attached the magazines below. Here is a link to the video explaining the problem https://youtu.be/5Mgz4QhXaQI

Custom view

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))); } } } 

Console Logs

 [![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 

enter image description here

enter image description here

+5
source share
2 answers

You just need to save boolean to indicate if you need to draw something. Currently, you arbitrarily draw the same thing at each iteration.

As stated by Romain Guy here :

In general, hardware layers should be installed on representations that are expensively attractive and whose content will not change frequently.

 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; } } 
+1
source

The problem is unnecessary work in onDraw . This method is called up to 60 times per second. Therefore, accessing resources or creating objects in this method degrades performance. Here is the fixed version:

 public class ConcentricCircularView extends View { private static final int COUNT = 10; private Paint paint; private DashPathEffect[] dashPaths = new DashPathEffect[COUNT]; private int halfWidth, halfHeight, radius; private int dimen15; public ConcentricCircularView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); // Get the dimensions. int dimen1 = dipToPixels(getResources().getDimension(R.dimen.d1)); int dimen10 = dipToPixels(getResources().getDimension(R.dimen.d10)); dimen15 = dipToPixels(getResources().getDimension(R.dimen.d15)); // Setup the path effects; for (int i=0; i<COUNT; i++) { dashPaths[i] = new DashPathEffect( new float[]{ 1, dimen10 + dimen1 * i }, 0); } // Setup the paint. paint = new Paint(); paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(dimen1); paint.setStrokeCap(Paint.Cap.ROUND); paint.setAntiAlias(true); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); halfWidth = w / 2; halfHeight = h / 2; radius = w / 3; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); for (int i=0; i<COUNT; i++) { paint.setPathEffect(dashPaths[i]); canvas.drawCircle(halfWidth, halfHeight, radius + dimen15 * i, paint); } } private int dipToPixels(float value) { final float scale = getResources().getDisplayMetrics().density; return (int) (value * scale + 0.5f); } } 
0
source

Source: https://habr.com/ru/post/1265766/


All Articles