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" />