Je travaille sur un projet de test qui est similaire à Voici une idée de ce que je fais en fait: P> digitalpaint code> exemple dans les démos de SDK Android. J'essayais de mettre en œuvre des fonctionnalités d'annulation / de redo dans mon projet, mais les choses que j'ai essayées ne fonctionnaient pas comme je m'attends. Je trouve des questions similaires à celles-ci sur Internet et ici, mais elles ne m'a pas aidées, c'est pourquoi je pose une nouvelle question.
public class MyView extends View {
//private static final float MINP = 0.25f;
//private static final float MAXP = 0.75f;
private Path mPath;
private Paint mBitmapPaint;
public MyView(Context c) {
super(c);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mCanvas.drawColor(Color.WHITE);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
5 Réponses :
Je pense que dans ce cas, vous pouvez utiliser deux toiles. Vous savez quand l'utilisateur commence à dessiner et lors de la fin. Donc, dans Cela devrait garantir que vous aurez l'état d'image précédent, mais je ne suis pas sûr de la performance. P> tactile_start code> Vous pouvez créer une copie de votre canvas actuelle. Lorsque l'utilisateur clique sur Annuler, vous remplacez votre toile actuelle avec précédemment enregistrée. P>
La meilleure solution est que vous implémentez votre propre moteur d'annulation / redro. p>
Enregistrez dans une matrice chaque action que vous effectuez dans une matrice (c.-à-d. Cercle [0] en position X1, Y1, [1] ligne de X2, Y2 à X3, Y3, etc.) P> li>
dessiner p> li>
Si vous avez besoin d'annuler, effacez la toile et repeindre toutes les actions N - 1 de [0] à [N-1] P> LI>
Si vous annulez plus, il suffit de peindre de [0] à [n-2], etc. p> li> ol>
J'espère que cela vous donne un indice p>
Cheer! p>
En fait, c'était mon idée, mais je veux savoir si c'est la meilleure chose à faire pour faire cela.
Je ne sais pas si c'est ce que vous aviez à l'esprit, mais c'est comme ça que je le fais. Au lieu de la stocker dans un seul chemin, vous stockez un tableau avec tous les chemins, comme celui-ci, l'utilisateur peut dessiner de nombreuses lignes, avec une petite modification que vous pouvez ajouter multi-touch aussi.
Pour faire annuler et refaire, il suffit de supprimer ou ajoutez le dernier chemin de chemin à partir de la variable CODE> PATHS CODE>
et stockez-les dans un nouveau tableau. Quelque chose comme: p> Voici mon panneau modifié, je ne peux pas l'essayer maintenant, mais les méthodes ci-dessus doivent fonctionner! J'espère que ça aide! (Il y a peu de variables supplémentaires simplement les supprimer :) p>
Merci mec! Cette mise en œuvre fonctionne comme un charme !!!! Juste besoin d'ajouter invalider (); code> dans
oncclickundo () code> et
onclickredo (); code> afin que vous puissiez obtenir le résultat juste après avoir cliqué sur le bouton .
Content d'aider :) J'ai ajouté la réponse! À votre santé!
Je viens de voir un problème en fait. Lorsque vous utilisez mpain.setxfermode (nouveau PorterSduffXFermode (PorterDuff.Mode.Clear)); code> avec votre code, le résultat est des lignes noires, elle n'agit pas comme une brosse. Et l'autre chose est si j'essaie de définir un effet sur l'accident vasculaire cérébral, cela change toutes les vieilles lignes aussi.
Eh bien, c'est parce que vous définissez un effet dans la peinture utilisée pour toutes les lignes que je suppose. Je ne sais vraiment pas comment vous aider à ce sujet, peut-être mettre à jour votre réponse avec plus de détails, puis nous pouvons essayer de trouver quelque chose de spécifique sur ce dont vous avez besoin!
@gameower: Hey je viens d'essayer ce code. Et cela me quitte de mon problème. Maintenant je veux une dernière chose. Je veux avoir une toile avec un bitmap de fond. J'ai fatigué plusieurs façons mais pas réussi. Pouvez-vous me dire où écrire cette méthode dessinée?
@HARDIKTRIVEDI Je vous suggère fortement de poser une question dans le forum et de laisser toute la communauté vous aider! J'ai besoin de voir une partie de votre source de sorte que je peux vous guider. Ajoutez le lien à votre question ici et je ferai de mon mieux pour vous aider!
@gameower Utilisation de votre code J'ai essayé d'implémenter une fonctionnalité d'annulation - Redo, mais je ne reçois toujours pas de solution de, au premier clic de l'annulation, la fonctionnalité ne fonctionne pas. J'ai utilisé Invalidate () Néanmoins, il ne fonctionne pas.
@anddev Veuillez ouvrir une nouvelle question pour cela, expliquer quel est votre problème et nous donner du code. Cette mise en œuvre fonctionne définitivement!
Yeh le code u fourni fonctionne bien. Mais supposons que je souhaite montrer aux images de sauvegarde sur la toile, puis je dois faire ce canevas.Drawbitmap (bitmaptocanvas, 0f, 0f, null); À l'intérieur de la méthode ONDRAW (Canvas Toivas). Donc, dès que j'ai utilisé ce code, l'annulation et le redo arrêtent de travailler, pourquoi cela se produit et comment résoudre ceci.
Le tableau stocke uniquement les chemins, pas des bitmaps. Vous devez garder une trace des deux. Postez-le comme une nouvelle question et je suis sûr que la communauté vous aidera davantage.
@ Android-Droid Bonjour Peut-on avoir une solution de ce problème?
@Dhavalkhant quel problème?
@gameower lors de l'utilisation de MPAIN.STEXFERMODE (Nouveau PorterDuffXFermode (PorterDuff.Mode.Clear)); Avec ce code, le résultat est des lignes noires. au niveau de l'API <11 pour niveau API> 11 setlayertype (vue.layer_type_software, null); Cela fonctionnera
Qu'est-ce que Circleradius?
Un moyen d'implémenter une fonctionnalité DO / REDO consiste à encapsuler un appel de méthode et toutes les infos nécessaires à l'appel dans un objet afin que vous puissiez le stocker et l'appeler plus tard - le modèle de commande .
Dans ce modèle, chaque action a son propre objet: DrawcirCommand, DrawPathCommand, FillcolorCommand, etc. dans chaque objet le tirage au sort ( ) La méthode est implémentée de manière unique, mais est toujours appelée dessinée (toile de toile) qui permet au CommandManager de parcourir les commandes. Pour annuler, vous appelez sur les objets appelant la méthode annulation (); p>
Chaque objet de commande implémente une interface p> un objet ressemblerait à: p> } p> Vos commandes sont ajoutées à la commande CommandManager: p> et pour annuler une commande juste appeler: p> Le commandmanager stocke les commandes dans une structure de données, par exemple liste qui lui permet d'itératif sur les objets de commande. p> Vous pouvez trouver un tutoriel complet Ici sur la manière d'implémenter le modèle de commande avec do / annuler pour le dessin de toile sur Android. p> ici est un autre tutoriel sur la manière dont la mise en oeuvre du modèle de commande en Java; p> p>
Heureusement, j'ai résolu ceci aujourd'hui. Je trouve un moyen de faire cela. Questions comme: dans l'activité. P> in xml p> Si vous avez une meilleure solution, vous pouvez me contacter. P> [Voici mon blog que j'écris dans p> http://blog.csdn.net/sky_pjf/article/details/51086901] p> p>
Quelles solutions avez-vous déjà essayées?
Celui-ci: Stackoverflow.com/Questtions/7633282/...