web-dev-qa-db-fra.com

Android: Dessiner une toile sur un ImageView

Je suis nouveau dans la programmation Android et ce que j'essaie de comprendre est la suivante:

Dans ma mise en page, j'ai un TextView, ImageView et Button, tous sur un LinearLayout orienté verticalement.

Je veux pouvoir dessiner dynamiquement des cercles dans ImageView, sans perturber le reste de ma mise en page (textview/button) J'essaie de créer un canevas et utilise la fonction drawcircle dans canevas 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 pour ça? Ou ma méthode est-elle fondamentalement fausse? Comment puis-je dessiner des cercles dans ImageView sans recréer toute ma mise en page? 

Merci!

28
sil

J'ai eu le même défi et je suis parvenu à la conclusion qu'écraser onDraw ne fonctionnerait au moins dans l'ensemble. Mon 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-lui une nouvelle toile.
  2. Dessinez l'image bitmap dans la toile.
  3. Dessinez tout ce que vous voulez dans la toile.
  4. Attachez la toile au 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));
30
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);
25
Joby Wilson Mathews

Je pense qu'une meilleure approche serait de créer un ImageView personnalisé et de remplacer 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 d'implémenter une logique qui vérifie s'il y a un nouveau bitmap à acquérir via la méthode update (), de sorte que le code dans onDraw ne s'exécute pas à chaque fois et ne surcharge pas le système.

Et utilisez ensuite votre vue personnalisée partout où vous en avez besoin. Le moyen le plus simple serait de le déclarer directement dans le fichier activity_layout.xml en tant que 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 puis l'accès est dans votre code comme n'importe quelle autre vue en utilisant:

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

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

Vous pouvez obtenir ce que vous voulez en créant dans votre package une classe qui étend la vue des classes et remplace sa méthode onDraw. tracez un cercle comme vous le souhaitez.

puis, au lieu d’ajouter imageView à la mise en page, ajoutez ceci votre propre vue dans la mise en page xml.

<LinearLayout>

 < TextView> < /TextView>

  < Button> < /Button>

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

</ LinearLayout>

Vérifiez le lien suivant pour les graphiques 2D. C'est un bon tutoriel à lire .  
http://organicandroid.blogspot.com/2010/08/starting-to-play-with-graphics.html
J'espère que cette aide:)

0
Javanator

Il y a plusieurs façons de faire ce que vous voulez, mais utiliser un ImageView comme vous le décrivez n'en fait pas partie. Une possibilité consiste à ce que ImageView affiche un dessin animable. Vous pouvez ensuite vous concentrer sur votre implémentation Drawable pour dessiner les cercles. Une autre consiste à créer un nouveau bitmap à chaque fois que vous souhaitez modifier l’image et à configurer le ImageView pour qu’il affiche le nouveau bitmap. Toutefois, la manière habituelle de procéder consiste à créer une sous-classe View personnalisée. Le projet de démonstration API sample contient un exemple de vue personnalisée et vous pouvez trouver de nombreux tutoriels avec Google.

0
Ted Hopp