画布的大小

时间:2013-03-28 11:36:24

标签: android

我有一个Android应用程序,它有几个片段。

在其中一个片段中,有

  1. 一个字母,
  2. 自定义视图,
  3. 带按钮的两个面板。
  4. 在自定义视图(第2项)中,我需要绘制几个图形,其中一个图形与视图的大小相关联,i。即应该有一个带有圆边的矩形,其大小等于画布的大小减去填充。

    为了做到这一点,我需要获得画布的宽度和高度。

    我尝试了以下事项:

    1. 在方法onSizeChanged中获取视图的尺寸(新的宽度/高度)。
    2. 在方法onLayout中获取视图的尺寸。
    3. onDraw方法(canvas.getWidth()/getHeight(), View.getMeasuredWidth()/getMeasuredHeight())获取视图的尺寸。
    4. 所有三种方法都返回相同的宽度和高度,并且所有这些方法都不起作用 - 数字太窄(仅填充可用空间的约60%而不是100%)并且太高(图的底部)不可见)。

      确定自定义视图的维度(RectF实例)的正确方法是什么?

      请注意,我在横向模式下在Nexus 7仿真器上测试此应用程序。

      更新1(2013年3月28日21:42 MSK)

      相应片段的XML文件:

      <?xml version="1.0" encoding="utf-8"?>
      <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" >
      
          <TextView
              android:id="@+id/textView1"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="Simulation"
              android:textAppearance="?android:attr/textAppearanceLarge" />
      
          <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" />
      
          <LinearLayout
              android:id="@+id/simulationExecutionPanel"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:layout_weight="0.1" >
      
              <Button
                  android:id="@+id/restartSimulationButton"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="@string/restart_simulation" />
      
              <Button
                  android:id="@+id/simulationStepButton"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="@string/simulation_step" />
      
              <Button
                  android:id="@+id/pauseButton"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="@string/pause" />
      
              <Button
                  android:id="@+id/continueButton"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="@string/continue_button" />
      
              <Button
                  android:id="@+id/simulateAdInfinitumButton"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="@string/simulate_ad_infinitum" />
      
              <TextView
                  android:id="@+id/textView2"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="@string/currentCycleLabel" />
      
              <TextView
                  android:id="@+id/currentCycleIndicator"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="Cycle"
                  android:textAppearance="?android:attr/textAppearanceMedium" />
      
          </LinearLayout>
      
          <LinearLayout
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:layout_weight="0.1" >
      
              <Button
                  android:id="@+id/addCompanyButton"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="@string/add_company2" />
      
              <Button
                  android:id="@+id/removeCompanyButton"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="@string/remove_company" />
      
              <Button
                  android:id="@+id/setLabourForceButton"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="@string/set_labour_force" />
          </LinearLayout>
      
      </LinearLayout>
      

      以下是视图的代码(@+id/simulation_canvas_view):

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

      这是用于计算圆角矩形尺寸的类:

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

      更新2

      这是截图:

      Screenshot

      更新3(2013年3月31日19:38 MSK):如果我从onLayoutonSizeChangedonMeasure报告的宽度中减去150,矩形显示正确。

      更新4(05.04.2013 21:07 MSK):以下是主要活动的布局:

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="horizontal" >
      
          <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" />
      
          <FrameLayout
              android:id="@+id/content_fragment2"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent" 
              class="co.altruix.ccp.android.impl.fragments.ContentFragment2"/>
      
      </LinearLayout>
      

3 个答案:

答案 0 :(得分:2)

我看到android:layout_height="wrap_content"的自定义视图。

在这种情况下,父/容器ViewGroup想要在测量此视图时知道内容的高度。

但是,要绘制内容,您需要依赖于布局测量的尺寸,而布局仍然不知道内容的高度。

android:layout_height设置为0dp,这将允许使用android:layout_weight属性,然后视图将根据可用空间预先测量高度。

此外,当再次测量布局时,onSizeChanged()足以告知您有关尺寸更改的信息。

答案 1 :(得分:1)

试试这个:

view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener(){
        @Override
        public void onGlobalLayout() {

        //capture view width and height here

    }//end onGlobalLayout()

        });

请参阅getViewTreeObserver().

答案 2 :(得分:1)

根据我对这个问题的评论:

您的顶级布局:您已将content_fragment2的宽度设置为fill_parent,因此它的宽度与其parent linearlayout的宽度相同。您可能希望menu_pane具有固定宽度,没有layout_weight,并且content_fragment2具有layout_width = 0px和layout_weight = 1。

很高兴这有帮助!

相关问题