缩放画布以编程方式适应视图 [英] Scale a Canvas to fit a View programmatically
问题描述
我正在寻找有关以下缩放问题的帮助.
我建立了自己的View
类(自定义视图),该类是Dialog
的子级.
在此自定义视图中,我从底部到顶部沿垂直方向绘制了一个图形.
该图可以大于或小于View
的大小.
因此,我想使用onDraw()
方法(参见下面的代码)将图形绘制到Canvas
(大于View
)上,然后缩放Canvas
以适合View
./p>
我尝试过的事情包括将ScaleAnimation
与duration=0
一起使用或调用canvas.scale()
方法.每次都一样的结果;该图未缩放.
我已经阅读了不同的主题,例如:
谢谢您的帮助.
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];
}
}
在Dialog
中使用的
layout.xml:
<com.android.Ui.VerticalGraphView
android:id="@+id/verticalGraphView"
android:layout_width="242dp"
android:layout_height="1000dp"
android:layout_centerInParent="true" />
-
您不应在onDraw()方法中更改布局.在onDraw方法中,您必须获取当前的布局状态并对其进行处理(并在其边界内绘制).
-
尝试计算所需的视图大小,然后设置布局参数.每次需要缩放时,再做一遍.如果需要更新,请调用invalidate().
I'm looking for help with the following scaling problem.
I have built my own View
class (custom view) which is a child of a Dialog
.
In this custom view I plot a graph in vertical direction from bottom to top.
The graph can be greater or less than the size of the View
.
Therefore I would like to draw the graph onto the Canvas
(which is greater than the View
) using the onDraw()
method (see code below) and later scale the Canvas
to fit into the View
.
Things I've tried already include using a ScaleAnimation
with duration=0
or calling the canvas.scale()
method. Everytime the same result; the graph is not scaled.
I already read different threads like:
How to resize a custom view programmatically?
Thank you for your help.
VerticalGraphView Code:
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 which is used in the Dialog
:
<com.android.Ui.VerticalGraphView
android:id="@+id/verticalGraphView"
android:layout_width="242dp"
android:layout_height="1000dp"
android:layout_centerInParent="true" />
you are not supposed to change the layout in the onDraw() method. in the onDraw method you have to take the current layout state and deal with it (and draw inside its boundaries).
try to calculate the needed size of the view , and then set the layout params . upon each time you need to scale , do it again . if an update is needed , call invalidate() .
这篇关于缩放画布以编程方式适应视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!