Afin de créer un jeu simple, j'ai utilisé un modèle qui dessine un canevas avec des bitmaps comme celui-ci:
private void doDraw(Canvas canvas) {
for (int i=0;i<8;i++)
for (int j=0;j<9;j++)
for (int k=0;k<7;k++) {
canvas.drawBitmap(mBits[allBits[i][j][k]], i*50 -k*7, j*50 -k*7, null); } }
(Le canevas est défini dans "run ()" / le SurfaceView vit dans un GameThread.)
Ma première question est de savoir comment effacer (ou redessiner) l' ensemble du canevas pour une nouvelle mise en page?
Deuxièmement, comment puis-je mettre à jour une partie seulement de l'écran?
// This is the routine that calls "doDraw":
public void run() {
while (mRun) {
Canvas c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
if (mMode == STATE_RUNNING)
updateGame();
doDraw(c); }
} finally {
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c); } } } }
la source
mSurfaceHolder.unlockCanvasAndPost(c)
et puisc = mSurfaceHolder.lockCanvas(null)
, alors le nouveauc
ne contient pas la même chose que le précédentc
. Vous ne pouvez pas mettre à jour uniquement une partie d'un SurfaceView, ce que l'OP demandait, je suppose.Canvas
garde de vieux dessins.Dessiner une couleur transparente avec le mode clair PorterDuff fait l'affaire pour ce que je voulais.
la source
Bitmap#eraseColor(Color.TRANSPARENT)
, comme dans la réponse de HeMac ci-dessous.Color.TRANSPARENT
c'est inutile.PorterDuff.Mode.CLEAR
est totalement suffisant pour unARGB_8888
bitmap, ce qui signifie définir l'alpha et la couleur sur [0, 0]. Une autre façon est d'utiliserColor.TRANSPARENT
avecPorterDuff.Mode.SRC
.J'ai trouvé ceci dans des groupes Google et cela a fonctionné pour moi.
Cela supprime les rectangles de dessins, etc. tout en conservant le bitmap défini.
la source
J'ai essayé la réponse de @mobistry:
canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
Mais cela n'a pas fonctionné pour moi.
La solution, pour moi, était:
canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY);
Peut-être que quelqu'un a le même problème.
la source
utilisez la méthode de réinitialisation de la classe Path
la source
la source
veuillez coller ci-dessous le code sur le constructeur de classe d'extension de surfaceview .............
codage constructeur
codage xml
essayez le code ci-dessus ...
la source
Voici le code d'un exemple minimal montrant que vous devez toujours redessiner chaque pixel du canevas à chaque image.
Cette activité dessine un nouveau Bitmap toutes les secondes sur SurfaceView, sans effacer l'écran auparavant. Si vous le testez, vous verrez que le bitmap n'est pas toujours écrit dans le même tampon, et l'écran alternera entre les deux tampons.
Je l'ai testé sur mon téléphone (Nexus S, Android 2.3.3) et sur l'émulateur (Android 2.2).
la source
SurfaceHolder.Callback
, pas seulementCallback
.Canvas
si nous voulons redessiner complètement l'écran entier. Cela rend vrai ma déclaration sur les "dessins précédents". LeCanvas
conserve les dessins précédents.Canvas
conserve les dessins précédents. Mais c'est totalement inutile, le problème est que lorsque vous utilisezlockCanvas()
vous ne savez pas ce que sont ces "dessins précédents", et ne pouvez rien supposer à leur sujet. Peut-être que s'il y a deux activités avec un SurfaceView de la même taille, elles partageront le même Canvas. Peut-être que vous obtenez un morceau de RAM non initialisée avec des octets aléatoires. Peut-être qu'il y a toujours le logo Google écrit dans le canevas. Tu ne peux pas savoir. Toute application qui ne dessine pas chaque pixel aprèslockCanvas(null)
est interrompue.Pour moi, appeler
Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
ou quelque chose de similaire ne fonctionnerait qu'après avoir touché l'écran. Donc, j'appellerais la ligne de code ci-dessus, mais l'écran ne s'effacerait qu'après avoir touché l'écran. Donc ce qui a fonctionné pour moi était d'appelerinvalidate()
suivi deinit()
qui est appelé au moment de la création pour initialiser la vue.la source
la source
Effacer sur Canvas dans java android est similaire à l'effacement de HTML Canvas via javascript avec globalCompositeOperation. La logique était similaire.
U choisira la logique DST_OUT (Destination Out).
Remarque: DST_OUT est plus utile car il peut effacer 50% si la couleur de la peinture a 50% alpha. Donc, pour être complètement transparent, l'alpha de la couleur doit être de 100%. Il est recommandé d'appliquer paint.setColor (Color.WHITE). Et assurez-vous que le format de l'image du canevas était RGBA_8888.
Une fois effacé, revenez au dessin normal avec SRC_OVER (Source Over).
La mise à jour de l'affichage de petite zone devra littéralement accéder au matériel graphique, et peut-être n'est-elle pas prise en charge.
Le plus proche pour des performances optimales est l'utilisation de plusieurs couches d'images.
la source
N'oubliez pas d'appeler invalidate ();
la source
invalidate
après avoir dessiné quelque chose?Essayez de supprimer la vue à onPause () d'une activité et ajoutez onRestart ()
LayoutYouAddedYourView.addView (YourCustomView); LayoutYouAddedYourView.removeView (YourCustomView);
Au moment où vous ajoutez votre vue, la méthode onDraw () est appelée.
YourCustomView, est une classe qui étend la classe View.
la source
Dans mon cas, je dessine ma toile en linéaire. Pour nettoyer et redessiner:
puis, j'appelle la classe avec les nouvelles valeurs:
C'est la classe Lienzo:
la source
Avec l'approche suivante, vous pouvez effacer toute la toile ou juste une partie de celle-ci.
N'oubliez pas de désactiver l'accélération matérielle car PorterDuff.Mode.CLEAR ne fonctionne pas avec l'accélération matérielle et enfin appeler
setWillNotDraw(false)
car nous surchargons laonDraw
méthode.la source
LAYER_TYPE_HARDWARE
pourLAYER_TYPE_SOFTWARE
Votre première exigence, comment effacer ou redessiner la toile entière - Réponse - utilisez la méthode canvas.drawColor (color.Black) pour effacer l'écran avec une couleur de noir ou tout ce que vous spécifiez.
Votre deuxième exigence, comment mettre à jour une partie de l'écran - Réponse - par exemple si vous voulez garder toutes les autres choses inchangées à l'écran mais dans une petite zone de l'écran pour afficher un entier (par exemple un compteur) qui augmente toutes les cinq secondes. puis utilisez la méthode canvas.drawrect pour dessiner cette petite zone en spécifiant gauche en haut à droite en bas et peignez. puis calculez la valeur de votre compteur (en utilisant postdalayed pendant 5 secondes etc., llike Handler.postDelayed (Runnable_Object, 5000);), convertissez-la en chaîne de texte, calculez les coordonnées x et y dans ce petit rect et utilisez la vue texte pour afficher le changement valeur de compteur.
la source
J'ai dû utiliser une passe de dessin distincte pour effacer la toile (verrouiller, dessiner et déverrouiller):
la source
Il suffit d'appeler
canvas.drawColor (Couleur.TRANSPARENT)
la source
Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
. Si je ne me trompe pas, la couleur peut en fait être n'importe quoi (ne doit pas être TRANSPARENTE) carPorterDuff.Mode.CLEAR
elle effacera simplement le clip actuel (comme percer un trou dans la toile).