Android:将canvas绘制到ImageView

我是android编程的新手,我想弄清楚的是这个;

在我的布局中,我有一个TextView,ImageView和Button,所有这些都在垂直方向的LinearLayout上。

我希望能够在ImageView中动态绘制圆圈,而不会干扰我的其余布局(textview / button)。 我正在尝试创建一个canvas,并使用canvas中的drawcircle函数来设置圆的位置。 然后以某种方式将该canvas绘制到我的imageview中。 我不能让这个工作,这有诀窍吗? 或者我的方法根本错了? 如何在不重新创建整个布局的情况下将图形绘制到ImageView?

谢谢!

Solutions Collecting From Web of "Android:将canvas绘制到ImageView"

我遇到了同样的挑战,并得出结论,覆盖onDraw至少在一般情况下不起作用。 我的博客解释了原因。 对我来说非常有效的是:

  1. 创建一个新的图像位图并为其附加一个全新的canvas。
  2. 将图像位图绘制到canvas中。
  3. 将所有其他内容绘制到canvas中。
  4. 将canvas附加到ImageView。

这是一个代码片段:

import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; ImageView myImageView = ... Bitmap myBitmap = ... Paint myRectPaint = ... int x1 = ... int y1 = ... int x2 = ... int y2 = ... //Create a new image bitmap and attach a brand new canvas to it Bitmap tempBitmap = Bitmap.createBitmap(myBitmap.getWidth(), myBitmap.getHeight(), Bitmap.Config.RGB_565); Canvas tempCanvas = new Canvas(tempBitmap); //Draw the image bitmap into the cavas tempCanvas.drawBitmap(myBitmap, 0, 0, null); //Draw everything else you want into the canvas, in this example a rectangle with rounded edges tempCanvas.drawRoundRect(new RectF(x1,y1,x2,y2), 2, 2, myPaint); //Attach the canvas to the ImageView myImageView.setImageDrawable(new BitmapDrawable(getResources(), tempBitmap)); 
  ImageView imageView=(ImageView) findViewById(R.id.image); Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.BLACK); canvas.drawCircle(50, 50, 10, paint); imageView.setImageBitmap(bitmap); 

我认为更好的方法是创建自定义ImageView并覆盖onDraw方法。 就像是:

 public class CustomView extends ImageView { public CustomView(Context context) { super(context); } public CustomView(Context context, AttributeSet attrst) { super(context, attrst); } public CustomView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } MyBitmapFactory bitMapFac = null; public void setBitmapFactory(MyBitmapFactory bitMapFac) { this.bitMapFac = bitMapFac; } @Override public void onDraw(Canvas canvas) { canvas.drawColor(Color.TRANSPARENT); /*instantiate a bitmap and draw stuff here, it could well be another class which you systematically update via a different thread so that you can get a fresh updated bitmap from, that you desire to be updated onto the custom ImageView. That will happen everytime onDraw has received a call ie something like:*/ Bitmap myBitmap = bitMapFac.update(); //where update returns the most up to date Bitmap //here you set the rectangles in which you want to draw the bitmap and pass the bitmap canvas.drawBitmap(myBitMap, new Rect(0,0,400,400), new Rect(0,0,240,135) , null); super.onDraw(canvas); //you need to call postInvalidate so that the system knows that it should redraw your custom ImageView this.postInvalidate(); } } 

最好实现一些逻辑来检查是否有通过update()方法获取的新位图,这样onDraw中的代码不会每次都执行并且会给系统带来开销。

然后在您需要的任何地方使用自定义视图。 最简单的方法是直接在activity_layout.xml中声明它:

   

然后使用以下命令访问您的代码,就像任何其他视图一样:

  customView = (CustomView) findViewById(R.id.customView); 

如果您有一个布局的xml,所有元素都以垂直方向排列。

您可以通过在包中创建一个扩展Class View并覆盖其onDraw方法的类来实现您想要的。 根据需要在其中绘制圆圈。

然后,而不是在布局中添加imageView,在xml布局中添加您自己的视图。如下所示

  < TextView> < /TextView> < Button> < /Button>   

检查以下链接以获取2D图形。 这是一个很棒的教程。
http://organicandroid.blogspot.com/2010/08/starting-to-play-with-graphics.html
希望这个帮助:)

有几种方法可以做你想要的,但是按照你描述的方式使用ImageView不是其中之一。 一种可能性是让ImageView显示animationDrawable。 然后,您可以专注于让Drawable实现绘制圆圈。 另一种方法是每次想要更改图像时创建一个新的Bitmap,并将ImageView设置为显示新的Bitmap。 但是,通常的做法是创建自定义View子类。 API演示示例项目有一个自定义视图示例,您可以在Google上find很多教程。