title: Size of a canvas
body: <p>I have an Android application, which has several fragments.</p>
  
  <p>In one of these fragments, there is</p>
  
  <ol>
  <li>a lettering,</li>
  <li>custom view,</li>
  <li>two panels with buttons.</li>
  </ol>
  
  <p>In the custom view (item 2) I need to draw several figures, one of which is tied to the size of the view, i. e. there should be a rectangle with rounded edges, whose size is equal to the size of the canvas minus padding.</p>
  
  <p>In order to do this, I need to get the width and height of the canvas.</p>
  
  <p>I tried following things:</p>
  
  <ol>
  <li>Get the dimensions of the view in the method <code>onSizeChanged</code> (new width/height).</li>
  <li>Get the dimensions of the view in the method <code>onLayout</code>.</li>
  <li>Get the dimensions of the view in <code>onDraw</code> method (<code>canvas.getWidth()/getHeight(), View.getMeasuredWidth()/getMeasuredHeight()</code>).</li>
  </ol>
  
  <p>All three methods return the same width and height and all of them don't work - the figure is too narrow (fills only approx. 60 % of available space instead of 100 %) and too tall (the bottom of the figure is not visible).</p>
  
  <p>What is the correct way to determine the dimensions (<code>RectF</code> instance) of a custom view?</p>
  
  <p>Note that I test this application on a Nexus 7 emulator in landscape mode.</p>
  
  <p><strong>Update 1 (28.03.2013 21:42 MSK)</strong></p>
  
  <p>The XML file of the corresponding fragment:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@+id/simulation_fragment"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:orientation="vertical" &gt;
  
      &lt;TextView
          android:id="@+id/textView1"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="Simulation"
          android:textAppearance="?android:attr/textAppearanceLarge" /&gt;
  
      &lt;co.mycompany.ccp.android.impl.simulationcanvas.SimulationCanvasView
          android:id="@+id/simulation_canvas_view"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_weight="0.8" /&gt;
  
      &lt;LinearLayout
          android:id="@+id/simulationExecutionPanel"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_weight="0.1" &gt;
  
          &lt;Button
              android:id="@+id/restartSimulationButton"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@string/restart_simulation" /&gt;
  
          &lt;Button
              android:id="@+id/simulationStepButton"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@string/simulation_step" /&gt;
  
          &lt;Button
              android:id="@+id/pauseButton"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@string/pause" /&gt;
  
          &lt;Button
              android:id="@+id/continueButton"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@string/continue_button" /&gt;
  
          &lt;Button
              android:id="@+id/simulateAdInfinitumButton"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@string/simulate_ad_infinitum" /&gt;
  
          &lt;TextView
              android:id="@+id/textView2"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@string/currentCycleLabel" /&gt;
  
          &lt;TextView
              android:id="@+id/currentCycleIndicator"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="Cycle"
              android:textAppearance="?android:attr/textAppearanceMedium" /&gt;
  
      &lt;/LinearLayout&gt;
  
      &lt;LinearLayout
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_weight="0.1" &gt;
  
          &lt;Button
              android:id="@+id/addCompanyButton"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@string/add_company2" /&gt;
  
          &lt;Button
              android:id="@+id/removeCompanyButton"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@string/remove_company" /&gt;
  
          &lt;Button
              android:id="@+id/setLabourForceButton"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@string/set_labour_force" /&gt;
      &lt;/LinearLayout&gt;
  
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>Here's the code of the view (<code>@+id/simulation_canvas_view</code>):</p>
  
  <pre><code>import co.mycompany.ccp.android.api.economypartsdimensioncalculator.EconomyPartsDimensionCalculator;
  import co.mycompany.ccp.android.api.systemboundary.SystemBoundaryGraphicsCalculator;
  import co.mycompany.ccp.android.impl.economypartsdimensioncalculator.DefaultEconomyPartsDimensionCalculator;
  import co.mycompany.ccp.android.impl.systemboundary.DefaultSystemBoundaryGraphicsCalculator;
  import android.content.Context;
  import android.graphics.Canvas;
  import android.graphics.Color;
  import android.graphics.Paint;
  import android.graphics.Rect;
  import android.graphics.RectF;
  import android.util.AttributeSet;
  import android.util.Log;
  import android.view.View;
  
  /**
   * @author DP118M
   * 
   */
  public class SimulationCanvasView extends View {
  
      private static final int SYSTEM_BOUNDARY_COLOUR = Color.LTGRAY;
  
      [...]
  
      private int width = -1;
      private int height= -1;
      private SystemBoundaryGraphicsCalculator systemBoundaryGraphicsCalculator = new DefaultSystemBoundaryGraphicsCalculator();
      [...]
      private Rect systemBoundaryDimensions = new Rect(100, 100, 100 + 100,
              100 + 100);
      private Rect externalEconomyDimensions;
  
      [...]
  
      public SimulationCanvasView(final Context aContext) {
          super(aContext);
      }
  
      public SimulationCanvasView(final Context context, final AttributeSet attrs) {
          super(context, attrs);
      }
  
      public SimulationCanvasView(final Context context,
              final AttributeSet attrs, int defStyle) {
          super(context, attrs, defStyle);
      }
  
      [...]
  
      private void updateSystemBoundaryGraphicsCalculatorDimensions() {
          systemBoundaryGraphicsCalculator.setCanvasHeight(height);
          systemBoundaryGraphicsCalculator.setCanvasWidth(width);
          try {
              systemBoundaryGraphicsCalculator.run();
              systemBoundaryDimensions = systemBoundaryGraphicsCalculator
                      .getSystemBoundaryDimensions();
          } catch (final Exception exception) {
              throw new RuntimeException(exception);
          }
      }
  
      @Override
      protected void onDraw(final Canvas aCanvas) {
          super.onDraw(aCanvas);
  
          this.width = this.getWidth();
          this.height = this.getHeight();
  
          updateSystemBoundaryGraphicsCalculatorDimensions();         
  
          [...]
  
          drawRectangleWithRoundedEdges(aCanvas, systemBoundaryDimensions,
                  SYSTEM_BOUNDARY_COLOUR);
  
          [...]
      }
  
      private void drawRectangleWithRoundedEdges(final Canvas aCanvas,
              final Rect aDimensions, int aStrokeColour) {
          final Paint paint = new Paint();
  
          paint.setColor(aStrokeColour);
          paint.setStrokeWidth(1);
          paint.setStyle(Paint.Style.STROKE);
  
          aCanvas.drawRoundRect(new RectF(aDimensions), 20, 20, paint);
      }   
  }
  </code></pre>
  
  <p>Here's the class for calculating the dimensions of the rounded rectangle:</p>
  
  <pre><code>package co.mycompany.ccp.android.impl.systemboundary;
  
  import android.graphics.Rect;
  import co.mycompany.ccp.android.api.systemboundary.SystemBoundaryGraphicsCalculator;
  
  /**
   * @author DP118M
   * 
   */
  public class DefaultSystemBoundaryGraphicsCalculator implements
          SystemBoundaryGraphicsCalculator {
      private int canvasWidth;
      private int canvasHeight;
      private int xPadding = SYSTEM_BOUNDARY_X_PADDING;
      private int yPadding = SYSTEM_BOUNDARY_Y_PADDING;
      private Rect systemBoundaryDimensions;
  
      public void setXPadding(final int xPadding) {
          this.xPadding = xPadding;
      }
  
      public void setYPadding(final int yPadding) {
          this.yPadding = yPadding;
      }
  
      @Override
      public Rect getSystemBoundaryDimensions() {
          return systemBoundaryDimensions;
      }
  
      @Override
      public void setCanvasWidth(final int width) {
          this.canvasWidth = width;
      }
  
      @Override
      public void setCanvasHeight(final int height) {
          this.canvasHeight = height;
      }
  
      @Override
      public void run() throws Exception {
          this.systemBoundaryDimensions = new Rect(0 + xPadding, 0 + yPadding,
                  Math.max(this.canvasWidth - xPadding, 0), Math.max(
                          this.canvasHeight - yPadding, 0));
      }
  }
  </code></pre>
  
  <p><strong>Update 2</strong>:</p>
  
  <p>Here's the screenshot:</p>
  
  <p><img src="https://i.stack.imgur.com/UQbxO.png" alt="Screenshot"></p>
  
  <p><strong>Update 3 (31.03.2013 19:38 MSK):</strong> If I subtract 150 from the width reported by <code>onLayout</code>, <code>onSizeChanged</code> or <code>onMeasure</code>, the rectangle is displayed correctly.</p>
  
  <p><strong>Update 4 (05.04.2013 21:07 MSK):</strong> Here's the layout of the main activity:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="horizontal" &gt;
  
      &lt;fragment
          android:id="@+id/menu_pane"
          android:layout_width="0px"
          android:layout_height="match_parent"
          android:layout_weight="1"
          class="co.altruix.ccp.android.impl.fragments.MenuFragment" /&gt;
  
      &lt;FrameLayout
          android:id="@+id/content_fragment2"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent" 
          class="co.altruix.ccp.android.impl.fragments.ContentFragment2"/&gt;
  
  &lt;/LinearLayout&gt;
  </code></pre>