Android 以编程方式缩放画布以适合视图

Android 以编程方式缩放画布以适合视图,android,scale,android-canvas,android-view,Android,Scale,Android Canvas,Android View,我正在寻找以下缩放问题的帮助 我已经构建了自己的视图类(自定义视图),它是对话框的子类。 在这个自定义视图中,我从下到上沿垂直方向绘制了一个图形。 图形可以大于或小于视图的大小。 因此,我想使用onDraw()方法(参见下面的代码)将图形绘制到画布上(大于视图),然后缩放画布以适应视图 我已经尝试过使用ScaleAnimation和duration=0或者调用canvas.scale()方法。每次都是相同的结果;图表没有缩放 我已经读过不同的文章,比如: 谢谢你的帮助 垂直图形视图代码: p

我正在寻找以下缩放问题的帮助

我已经构建了自己的
视图
类(自定义视图),它是
对话框
的子类。 在这个自定义视图中,我从下到上沿垂直方向绘制了一个图形。 图形可以大于或小于
视图的大小。
因此,我想使用
onDraw()
方法(参见下面的代码)将图形绘制到
画布上(大于
视图
),然后缩放
画布以适应
视图

我已经尝试过使用
ScaleAnimation
duration=0
或者调用
canvas.scale()
方法。每次都是相同的结果;图表没有缩放

我已经读过不同的文章,比如:

谢谢你的帮助

垂直图形视图代码:

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];
    }
}
  • 不应该在onDraw()方法中更改布局。在onDraw方法中,您必须采用当前布局状态并处理它(并在其边界内绘制)

  • 尝试计算视图所需的大小,然后设置布局参数。每次需要缩放时,请再次缩放。如果需要更新,请调用invalidate()


  • 谢谢你的回答。为了清楚起见,我应该尝试将视图的大小设置为给定数据所需的大小,这是否正确。在本例中,我将通过LayoutParams将大小设置为1000。然后我可以在画布上画画。最后,我通过LayoutParams将视图的大小重置为我想要的大小(隐式完成缩放),然后调用invalidate()使更改可见?对吗?我不太明白。为什么要将视图的大小更改两次?如果您知道应该是什么大小,只需更改一次(使用setLayoutParams)即可。如果将来需要再次更改,请计算所需的大小,然后再次设置。我只想使用设置大小机制在画布上绘制,该画布大于我要显示的视图大小,因为我在大(1000px)画布上绘制每个像素。后面的视图更小(大约50%)。现在,我将LayoutParams设置为数据的大小1000,并在末尾重置onDraw()中的LayoutParams。(我从不调用invalidate(),因为我已经在执行onDraw()-方法)。问题仍然是,图形只是被切掉了,但没有缩放到正确的大小。现在我明白了。那么,在一个大的位图中绘制你想要的东西怎么样?在onDraw过程中,你只获取位图中对视图感兴趣的部分?视图不需要绘制到最终用户看不到的区域(例如,在屏幕外)。如果我可以在onDraw中将其缩放到所需的大小,则绘制到大位图会很好。我需要整个图形/整个位图,但需要缩放。用户应看到孔图形,但应将其缩放到视图的LayoutParams已给出的正确大小。
    <com.android.Ui.VerticalGraphView 
        android:id="@+id/verticalGraphView"
        android:layout_width="242dp"
        android:layout_height="1000dp"
        android:layout_centerInParent="true" />