Android自定义View:onDraw前是否有可获取宽高的方法以避免重复计算?
onSizeChanged() for One-Time Radius Calculation Absolutely! You’re right to want to avoid recalculating circleRadius every time onDraw() runs—since onDraw() can be triggered frequently (during scrolling, animations, or system redraws), redundant computations add unnecessary overhead.
The ideal method to handle this calculation is onSizeChanged(), which is part of the View lifecycle specifically for when your View's dimensions are set or updated. Here’s why it’s perfect:
- It’s called after the View has been measured and laid out, so
getWidth()(or thewparameter passed to the method) will have a valid, non-zero value—something you can’t rely on in the constructor. - It only runs when the View’s size changes (including the first time it’s initialized), not on every draw pass.
Example Implementation
private float circleRadius; private static final int CIRCLES_TO_FIT_AT_ONCE = 5; // Replace with your actual value @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); // Calculate radius here once, using the valid width value // Cast to float to avoid integer division truncation issues circleRadius = w / (float)CIRCLES_TO_FIT_AT_ONCE / 2; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // Use the precomputed circleRadius directly in your draw call canvas.drawCircle( getWidth() / 2 + (i - startIndex) * circleRadius * 2, getHeight() / 2, circleRadius, paint ); }
Bonus: Alternative Option (onLayout())
If you prefer, you could also use onLayout(), which is called when the View positions itself and its children. However, onSizeChanged() is more focused on dimension changes and is generally the cleaner choice for this specific task.
内容的提问来源于stack exchange,提问作者Moffen

