39

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

在我的布局中,我有一个 TextView、ImageView 和 Button,它们都在一个垂直方向的 LinearLayout 上。

我希望能够在 ImageView 中动态绘制圆圈,而不会干扰我的其余布局(文本视图/按钮)。我正在尝试创建一个画布,并使用画布中的 drawcircle 函数来设置圆圈的位置。然后以某种方式将该画布绘制到我的 imageview 上。我无法让它工作,这有什么诀窍吗?还是我的方法根本上是错误的?在不重新创建整个布局的情况下,我将如何在 ImageView 上绘制圆圈?

谢谢!

4

5 回答 5

34

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

  1. 创建一个新的图像位图并将一个全新的画布附加到它上面。
  2. 将图像位图绘制到画布中。
  3. 将您想要的所有其他内容绘制到画布中。
  4. 将画布附加到 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));
于 2012-06-11T18:58:59.407 回答
33
     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);
于 2015-02-14T09:36:03.157 回答
8

我认为更好的方法是创建自定义 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 i.e. 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 中声明它,如下所示:

   <com.mycustomviews.CustomView
        android:id="@+id/customView"
        android:layout_centerInParent="true"
        android:layout_height="135dp"
        android:layout_width="240dp"
       android:background="@android:color/transparent"/>

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

   customView = (CustomView) findViewById(R.id.customView);
于 2015-09-15T12:05:26.807 回答
0

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

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

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

<线性布局>

 < TextView> < /TextView>

  < Button> < /Button>

  <com.prac.MyView> </ com.prac.MyView>

</线性布局>

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

于 2011-02-07T04:49:16.247 回答
0

有几种方法可以做你想做的事,但使用 ImageView 你描述的方式不是其中之一。一种可能性是让 ImageView 显示动画 Drawable。然后,您可以专注于让您的 Drawable 实现绘制圆圈。另一种是每次希望图像发生变化时都创建一个新的Bitmap,并设置ImageView来显示新的Bitmap。但是,通常的做法是创建一个自定义 View 子类。API Demos示例项目有一个自定义视图的示例,您可以在 Google 上找到很多教程。

于 2011-02-07T04:53:41.570 回答