Android: Define onDraw Canvas Size

AndrewLugs picture AndrewLugs · Jan 23, 2013 · Viewed 14.4k times · Source

I've removed my old code now as it wasn't working as I intended. I was trying to use the onDraw canvas feature within a certain portion of the screen so that I could still have buttons and other text around my drawing.

***EDIT***

I've managed to fix this issue now. A lot of what was suggested was helpful but I just couldn't get it to work with what I wanted. That's probably more my fault than anything else so thanks to all those who offered advice. Here's how I solved the issue.

*1. First Define a View in the Layout File.

<view
class="com.project.MainActivity.Drawing"
android:id="@+id/drawing_area"
android:layout_width="700dp"
android:layout_height="900dp"
android:layout_centerInParent="true"/>

*2. Then create a separate java class file with the following code:

public class Drawing extends View {
Paint paint = new Paint();

public Drawing(Context context) {
super(context);
}

public Drawing(Context context, AttributeSet attrs) {
super(context, attrs);
}   

@Override
protected void onDraw(Canvas canvas) {  
super.onDraw(canvas);

//Draw Image Here//

}

*3. Then call the Drawing from the main activity:

public class MainActivity extends Activity {

private Drawing mDrawingArea;

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.percentage_count_layout);
  mDrawingArea = (Drawing)findViewById(R.id.drawing_area);  
}

Answer

D-Dᴙum picture D-Dᴙum · Jan 23, 2013

In your View class you need to override the onMeasure() method. This is where you ask for a specific View size. There are some official Android tutorials on this subject and I will edit this post once I'm at my computer with the links.

EDIT:

Take a look at this Android article about creating custom components.. Specifically take a look at the section titled 'Extend onDraw() and onMeasure()'. Quoting:

onMeasure() is a little more involved. onMeasure() is a critical piece of the rendering contract between your component and its container. onMeasure() should be overridden to efficiently and accurately report the measurements of its contained parts. This is made slightly more complex by the requirements of limits from the parent (which are passed in to the onMeasure() method) and by the requirement to call the setMeasuredDimension() method with the measured width and height once they have been calculated. If you fail to call this method from an overridden onMeasure() method, the result will be an exception at measurement time.

Further on in the article:

Your component's onMeasure() method should calculate a measurement width and height which will be required to render the component. It should try to stay within the specifications passed in, although it can choose to exceed them (in this case, the parent can choose what to do, including clipping, scrolling, throwing an exception, or asking the onMeasure() to try again, perhaps with different measurement specifications).

There is an CustomView example available as a demo but unfortunately the developer website has changed (for the worse!) so that it's not available except through download by the SDK Manager. See the page here for more instructions.