web-dev-qa-db-ja.com

Android:ImageViewへのキャンバスの描画

私はAndroidプログラミングが初めてで、私が理解しようとしているのはこれです。

私のレイアウトでは、TextView、ImageView、およびButtonがすべて垂直方向のLinearLayout上にあります。

レイアウトの残りの部分(textview/button)を妨げることなく、ImageViewで動的に円を描画できるようにしたいと思います。キャンバスを作成し、キャンバス内でdrawcircle関数を使用して円の位置を設定しようとしています。そして、そのキャンバスを何らかの方法で私のimageviewに描画します。私はこれを機能させることができません、これにトリックはありますか?または私の方法は根本的に間違っていますか?レイアウト全体を再作成せずに、ImageViewに円を描くにはどうすればよいですか?

ありがとう!

32
sil

私も同じ課題を抱えていましたが、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));
31
Nantoka
     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);
27

より良いアプローチは、カスタム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);
5
Lys

すべての要素が垂直方向に配置されたレイアウトのxmlがある場合。

クラスビューを拡張し、onDrawメソッドをオーバーライドするクラスをパッケージに作成することで、目的を達成できます。必要に応じてその中に円を描きます。

次に、レイアウトにimageViewを追加する代わりに、次のような独自のビューをxmlレイアウトに追加します。

<LinearLayout>

 < TextView> < /TextView>

  < Button> < /Button>

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

</ LinearLayout>

2Dグラフィックについては、次のリンクを確認してください。読むべきすばらしいチュートリアルです。
http://organicandroid.blogspot.com/2010/08/starting-to-play-with-graphics.html
このヘルプをご覧ください:)

0
Javanator

希望することを行うにはいくつかの方法がありますが、ImageViewを使用して説明する方法はそれらの1つではありません。 1つの可能性は、ImageViewにアニメーション化されたDrawableを表示させることです。その後、Drawable実装で円を描くことに集中できます。もう1つは、イメージを変更するたびに新しいビットマップを作成し、新しいビットマップを表示するようにImageViewを設定することです。ただし、これを行う通常の方法は、カスタムビューサブクラスを作成することです。 API Demos サンプルプロジェクトにはカスタムビューの例があり、Googleで多くのチュートリアルを見つけることができます。

0
Ted Hopp