2012-06-17 57 views
0

我正在寻找有关以下缩放问题的帮助。以编程方式缩放画布以适合视图

我已经建立了我自己的View类(自定义视图),它是Dialog的孩子。 在这个自定义视图中,我从下到上绘制了一个垂直方向的图。 该图可以大于或小于View的大小。 因此,我想使用onDraw()方法(见下面的代码)将图表绘制到Canvas(它大于View),然后将Canvas标定为View

我试过的东西已经包括使用ScaleAnimationduration=0或调用canvas.scale()方法。每次都有相同的结果;该图不是缩放的。

我已经阅读不同的线程,如:

How to resize a custom view programmatically?

Android scale view

谢谢您的帮助。

VerticalGraphView代码:

public class VerticalGraphView extends View { 
    private static final String TAG = "VerticalGraphView"; 

    private int[] ch1_data = new int[1000]; 
    private int[] ch2_data = new int[1000]; 
    private int mCanvasHeight = 1000; 
    private int mCanvasWidth = 242; 
    private Paint ch1_color = new Paint(); 
    private Paint ch2_color = new Paint(); 
    private Paint zero_color = new Paint(); 
    private Paint grid_paint = new Paint(); 
    private Paint outline_paint = new Paint(); 

    public VerticalGraphView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     Log.d(TAG, "VerticalGraphView-Constructor called!"); 
    } 

    protected void onFinishInflate() { 
     super.onFinishInflate(); 
     Log.d(TAG, "onFinishInflate()-called!"); 

    // Log.i(TAG, "New Size set for height = " + setSizeHeight); 
    } 

    protected void onDraw(Canvas canvas) { 
     Log.d(TAG, "onDraw()-called!"); 

    // // RESIZE TO FIT THE DATA 
    // Bitmap b = Bitmap.createBitmap(mCanvasWidth, ch1_data.length, Bitmap.Config.ARGB_8888); 
    // Canvas canvas = new Canvas(b); 
    // canvas.setBitmap(b); 

     ch1_color.setColor(Color.BLUE);     
     ch2_color.setColor(Color.RED); 

     zero_color.setColor(Color.argb(80,0,0,00)); 
     zero_color.setStrokeWidth(3f); 

     grid_paint.setColor(Color.rgb(200, 200, 200)); 

     outline_paint.setColor(Color.BLACK); 
     outline_paint.setStrokeWidth(2f); 

     if (canvas != null) { 
      // Redraw the background 
      canvas.drawRGB(255, 255, 255); 

      // Draw vertical grey lines 
      for (int vertical = 1; vertical<6; vertical++) { 
       if (vertical == 3) { // Draw line in the middle 
        canvas.drawLine(vertical*(mCanvasWidth/6)+1, 1, 
            vertical*(mCanvasWidth/6)+1, 
            mCanvasHeight+1, 
            zero_color); 
       } else { 
        canvas.drawLine(vertical*(mCanvasWidth/6)+1, 1, 
            vertical*(mCanvasWidth/6)+1, 
            mCanvasHeight+1, 
            grid_paint); 
       } 
      }    

      // Draw horizontal grey lines 
      for (int horizontal = 1; horizontal<10; horizontal++) { 
       canvas.drawLine(1, horizontal*(mCanvasHeight/10)+1, 
           mCanvasWidth+1, 
           horizontal*(mCanvasHeight/10)+1, 
           grid_paint); 
      } 

      // draw outline 
      canvas.drawLine(0, 0, (mCanvasWidth+1), 0, outline_paint); // top 
      canvas.drawLine((mCanvasWidth), 0, (mCanvasWidth), (mCanvasHeight+1), 
          outline_paint); //right 
      canvas.drawLine(0, (mCanvasHeight), (mCanvasWidth), (mCanvasHeight), 
          outline_paint); // bottom 
      canvas.drawLine(0, 0, 0, (mCanvasHeight+1), outline_paint); //left 

      // plot data 
      int middle = mCanvasWidth/2; 

      for (int x=0; x<(ch2_data.length-1); x++) {     
       canvas.drawLine((middle + ch2_data[x]),(mCanvasHeight - x), 
           (middle + ch2_data[x+1]), 
           (mCanvasHeight - x+1), 
           ch2_color); 
       canvas.drawLine((middle + ch1_data[x]),(mCanvasHeight - x), 
           (middle + ch1_data[x+1]), 
           (mCanvasHeight - x+1), 
           ch1_color); 
      } 
     } 

     Log.e(TAG, "canvas.Height = " + canvas.getHeight()); 
     Log.e(TAG, "canvas.Width = " + canvas.getWidth()); 

     // RESIZE TO FIT THE VIEW, only in Y-Direction 
     // Fits the canvas onto the view 
     float ratio = ((float) canvas.getHeight())/(float) mCanvasHeight; 
     Log.e(TAG, "SCALE: ratio = " + ratio); 

    // ScaleAnimation anim = new ScaleAnimation(1f,1f,1f,ratio, 0.5f, 0.5f); 
    // anim.setDuration(1000); 
    // this.startAnimation(anim); 

    // canvas.scale(0f, ratio, canvas.getWidth() * 0.5f , canvas.getHeight() * 0.5f); 

    // canvas.save(Canvas.MATRIX_SAVE_FLAG); 
    // canvas.scale(0f, ratio, mCanvasWidth * 0.5f , mCanvasHeight * 0.5f); 
    // canvas.restore(); 

    // canvas.scale(0f, 0.5f, mCanvasWidth * 0.5f , mCanvasHeight * 0.5f); 
    // canvas.scale(100, 100); 
    // canvas.getMatrix().postScale(0.5f, 0.5f); 

     RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(242, 500); 
    // params.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE); 
     params.addRule(RelativeLayout.CENTER_IN_PARENT); 
     this.setLayoutParams(params); 

    // RelativeLayout layout = (RelativeLayout) findViewById(R.id.relativeLayoutRight); 
    // ViewGroup.LayoutParams params = layout.getLayoutParams(); 
    // params.height = 500; 
    // params.width = canvas.getWidth(); 
    // layout.setLayoutParams(params); 
    // invalidate(); 

    // DRAW THE CANVAS 
     super.onDraw(canvas); 
    }   

    public void setData(int[] data1, int[] data2) { 
     Log.d(TAG, "setData()-called!"); 
     ch1_data = data1; 
     ch2_data = data2; 
    } 

    /** 
    * This method sets the height of the View.</br> 
    * <b><u>NOTE:</u></b> The method call deletes all data stored for the graph. 
    * @param newHeight the new height of the view 
    */ 

    public void setHeight(int newHeight) { 
     mCanvasHeight = newHeight; 
     ch1_data = new int[newHeight]; 
     ch2_data = new int[newHeight]; 
    } 
} 

layout.xml这是在Dialog使用:你不应该

<com.android.Ui.VerticalGraphView 
    android:id="@+id/verticalGraphView" 
    android:layout_width="242dp" 
    android:layout_height="1000dp" 
    android:layout_centerInParent="true" /> 

回答

0
  1. 中的onDraw()方法来改变布局。在onDraw方法中,您必须采用当前布局状态并进行处理(并在其边界内绘制)。

  2. 尝试计算视图所需的大小,然后设置布局参数。每次你需要扩展时,都要重新做一次。如果需要更新,请调用invalidate()。

+0

谢谢你的回答。为了清楚起见,我应该尝试将视图的大小设置为给定数据所需的大小是正确的。在示例中,我将通过LayoutParams将大小设置为1000.之后,我可以在画布上绘制。最后,我通过LayoutParams将视图的大小重置为我想要的大小(缩放隐式完成),并且我调用invalidate()使更改可见?正确? – milius

+0

不知道我明白。你为什么要改变视图的大小两次?如果你知道应该是什么大小,只需更改一次(使用setLayoutParams),就是这样。如果将来需要再次更改,请计算所需的大小,然后重新设置。 –

+0

我只想使用setSize-machanism绘制一个大于我想要显示的视图大小的画布,因为我在大(1000px)画布上绘制每个像素。后来的观点较小(50%左右)。现在我将LayoutParams设置为1000的数据大小,并在最后重置onDraw()中的LayoutParams。 (我从来没有调用invalidate(),因为我已经在执行onDraw()方法)。问题仍然是图表被切断,但没有缩放到正确的大小。 – milius