2011-02-07 5 views
23

Je suis nouveau à la programmation android et ce que j'essaie de comprendre est ceci;Android: Dessin d'une toile à un ImageView

Dans ma mise en page, j'ai un TextView, ImageView, et Button, le tout sur un LinearLayout orienté verticalement. Je veux être capable de dessiner des cercles dynamiquement dans l'ImageView, sans déranger le reste de ma mise en page (vue/bouton texte). J'essaie de créer un canevas et d'utiliser la fonction drawcircle dans canvas pour définir l'emplacement du cercle. Et puis dessinez cette toile à mon imageview d'une certaine manière. Je n'arrive pas à faire fonctionner ça, y a-t-il un truc à faire? Ou ma méthode est-elle fondamentalement erronée? Comment irais-je dessiner des cercles sur ImageView sans recréer toute ma mise en page?

Merci!

Répondre

0

Si vous avez un XML avec mise en page avec tous vos éléments disposés en orientation verticale.

Vous pouvez obtenir ce que vous voulez en créant une classe dans votre package qui étend la vue de classe et remplace sa méthode onDraw. dessinez un cercle dedans comme vous voulez.

alors au lieu d'ajouter imageView dans la mise en page ajouter ce votre propre point de vue dans le fichier XML layout.like les éléments suivants

< LinearLayout>

< TextView> < /TextView> 

    < Button> < /Button> 

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

</LinearLayout>

Vérifiez le lien suivant pour Graphiques 2D. C'est un excellent tutoriel à lire.
http://organicandroid.blogspot.com/2010/08/starting-to-play-with-graphics.html
Hope this aide:)

+0

S'il vous plaît mettre à jour le lien. Blog est supprimé –

0

Il y a deux façons de faire ce que vous voulez, mais en utilisant un ImageView la façon dont vous décrivez n'est pas un d'entre eux. Une possibilité est d'avoir le ImageView afficher un dessin animé. Vous pouvez ensuite vous concentrer sur le fait que votre implémentation Drawable dessine les cercles. Une autre consiste à créer un nouveau bitmap chaque fois que vous voulez que l'image change et à définir ImageView pour afficher le nouveau bitmap. La manière habituelle de le faire, cependant, est de créer une sous-classe View personnalisée. L'exemple de projet API Demos présente un exemple de vue personnalisée et vous pouvez trouver de nombreux didacticiels avec Google.

26

J'ai eu le même défi et suis arrivé à la conclusion que l'écrasement d'onDraw ne fonctionnera pas au moins dans le cas général. My blog explique les raisons. Ce qui a très bien fonctionné pour moi est le suivant:

  1. Créez une nouvelle image bitmap et attachez-y une toute nouvelle toile.
  2. Dessinez le bitmap d'image dans le canevas.
  3. Dessinez tout ce que vous voulez dans le canevas.
  4. Associez le canevas à ImageView.

Voici un extrait de code pour cela:

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)); 
+0

Merci, fonctionne bien – Lilo

+5

Juste une suggestion que je suis tombé sur le même problème, Au lieu de créer un nouveau BitmapDrawable, Nous pouvons également utiliser la fonction myImageView.setImageBitmap (tempBitmap)! – balachandarkm

20
 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); 
+0

et si je veux supprimer le canevas après setImageBitmap? –

2

Je pense qu'une meilleure approche serait de créer un ImageView personnalisé et Substituez la méthode onDraw.Quelque chose comme:

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(); 
} 
} 

Ce serait une bonne idée de mettre en œuvre une logique qui vérifie s'il y a un bitmap frais d'acquisition par la méthode mise à jour(), de sorte que le code à l'intérieur onDraw ne sera pas exécuté à chaque fois et mettre les frais généraux au système.

Et puis utilisez votre vue personnalisée où vous en avez besoin. La façon la plus simple serait de déclarer directement à l'intérieur du activity_layout.xml comme tel:

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

Et l'accès est dans votre code comme tout autre point de vue en utilisant:

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