Android SDK: Erstellen einer Zeichnungs-App - Interaktion mit Hilfe der Berührung
German (Deutsch) translation by Katharina Grigorovich-Nevolina (you can also view the original English article)
In dieser Serie erstellen wir eine Fingermalerei-App für Android mit Hilfe der Berührung. Der Benutzer kann aus einer Farbpalette auswählen, eine Pinselgröße auswählen, löschen, eine neue Zeichnung erstellen oder die vorhandene Zeichnung in der Gerätegalerie speichern.
Serienformat
Diese Serie zum Erstellen einer Zeichnungs-App besteht aus drei Teilen:
Endgültige Vorschau



Im ersten Teil der Serie haben wir die Benutzeroberfläche erstellt. In diesem zweiten Teil werden wir die Zeichnung auf der Leinwand implementieren und Farben auswählen. Im letzten Teil der Serie werden wir die Möglichkeit zum Löschen, zum Erstellen neuer Zeichnungen und zum Speichern einer Zeichnung in der Galerie auf dem Benutzergerät vorstellen. Wir werden Optionen prüfen, die Sie verwenden können, um diese App in zukünftigen Tutorials zu verbessern, einschließlich Musterfüllungen, Opazität und und Interaktion außer Touchscreen.
1. Bereiten Sie sich auf das Zeichnen vor
Schritt 1
Letztes Mal haben wir eine Klasse mit dem Namen "DrawingView" erstellt, die eine benutzerdefinierte Ansicht ist, in der die Zeichnungsfunktionen stattfinden. Wir haben die Gliederung der Klassendeklaration und eine Methode mit dem Namen "setupDrawing" erstellt - wir werden das jetzt implementieren. Fügen Sie in Ihrer DrawingView-Klasse die folgenden Importanweisungen hinzu:
1 |
import android.graphics.Bitmap; |
2 |
import android.graphics.Canvas; |
3 |
import android.graphics.Paint; |
4 |
import android.graphics.Path; |
5 |
import android.view.MotionEvent; |
Als nächstes fügen Sie einige Instanzvariablen oben in der Klasse hinzu:
1 |
//drawing path
|
2 |
private Path drawPath; |
3 |
//drawing and canvas paint
|
4 |
private Paint drawPaint, canvasPaint; |
5 |
//initial color
|
6 |
private int paintColor = 0xFF660000; |
7 |
//canvas
|
8 |
private Canvas drawCanvas; |
9 |
//canvas bitmap
|
10 |
private Bitmap canvasBitmap; |
Wenn der Benutzer den Bildschirm berührt und den Finger zum Zeichnen bewegt, verwenden wir einen Pfad, um die Zeichenaktion auf der Leinwand zu verfolgen. Sowohl die Leinwand als auch die darüberliegende Zeichnung werden durch Paint-Objekte dargestellt. Die anfängliche Farbe entspricht der ersten Farbe in der Palette, die wir zuletzt erstellt haben und die beim Start der App zunächst ausgewählt wird. Schließlich deklarieren wir Variablen für die Leinwand und die Bitmap, die mit drawPaint gezeichneten Benutzerpfade werden auf die Leinwand gezeichnet, die mit canvasPaint gezeichnet wird.
Schritt 2
Lassen Sie uns nun einige dieser Variablen in der setupDrawing-Methode instanziieren, um die Klasse für das Zeichnen einzurichten. Instanziieren Sie zuerst die Zeichnungspfad- und Malobjekte:
1 |
drawPath = new Path(); |
2 |
drawPaint = new Paint(); |
Als nächstes legen Sie die Anfangsfarbe fest:
1 |
drawPaint.setColor(paintColor); |
Legen Sie nun die anfänglichen Pfadeigenschaften fest:
1 |
drawPaint.setAntiAlias(true); |
2 |
drawPaint.setStrokeWidth(20); |
3 |
drawPaint.setStyle(Paint.Style.STROKE); |
4 |
drawPaint.setStrokeJoin(Paint.Join.ROUND); |
5 |
drawPaint.setStrokeCap(Paint.Cap.ROUND); |
Wir werden einen Teil dieses Codes im nächsten Tutorial ändern, wenn wir die Möglichkeit zur Auswahl der Pinselgröße implementieren. Jetzt legen wir eine beliebige Pinselgröße fest. Durch das Festlegen der Anti-Alias-, Strichverbindungs- und Kappenstile werden die Zeichnungen des Benutzers weicher dargestellt.
Schließen Sie die setupDrawing-Methode ab, indem Sie das Canvas-Paint-Objekt instanziieren:
1 |
canvasPaint = new Paint(Paint.DITHER_FLAG); |
Dieses Mal setzen wir das Dithering, indem wir einen Parameter an den Konstruktor übergeben.
Schritt 3
Wir müssen einige Methoden überschreiben, um die benutzerdefinierte Ansichtsfunktion als Zeichnungsansicht zu erstellen. Überschreiben Sie noch in der DrawingView-Klasse die onSizeChanged-Methode, die aufgerufen wird, wenn der benutzerdefinierten Ansicht eine Größe zugewiesen wird:
1 |
@Override
|
2 |
protected void onSizeChanged(int w, int h, int oldw, int oldh) { |
3 |
//view given size
|
4 |
}
|
Rufen Sie in dieser Methode zuerst die Superklassenmethode auf:
1 |
super.onSizeChanged(w, h, oldw, oldh); |
Instanziieren Sie jetzt den Zeichenbereich und die Bitmap mit den Werten für Breite und Höhe:
1 |
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); |
2 |
drawCanvas = new Canvas(canvasBitmap); |
Schritt 4
Damit die Klasse als benutzerdefinierte Zeichnungsansicht fungieren kann, müssen Sie auch die onDraw-Methode überschreiben. Fügen Sie sie jetzt der Klasse hinzu:
1 |
@Override
|
2 |
protected void onDraw(Canvas canvas) { |
3 |
//draw view
|
4 |
}
|
Zeichnen Sie innerhalb der Methode die Leinwand und den Zeichenpfad:
1 |
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint); |
2 |
canvas.drawPath(drawPath, drawPaint); |
Die Möglichkeit für den Benutzer, den Pfad mit dem Zeichnungs-Paint zu zeichnen, wurde noch nicht implementiert. Sobald wir das getan haben, wird er in der Ansicht dargestellt. Jedes Mal, wenn der Benutzer mit Berührung-Interaktion zeichnet, wird die Ansicht ungültig, wodurch die onDraw-Methode ausgeführt wird.
2. Zeichnen erleichtern
Schritt 1
Wenn sich die Zeichnungsansicht auf dem App-Bildschirm befindet, möchten wir, dass der Benutzer sie als Zeichenoperationen registriert. Dazu müssen wir auf Berührungsereignisse achten. Fügen Sie in Ihrer drawingView-Klasse die folgende Methode hinzu:
1 |
@Override
|
2 |
public boolean onTouchEvent(MotionEvent event) { |
3 |
//detect user touch
|
4 |
}
|
Rufen Sie innerhalb der Methode die X- und Y-Positionen der Benutzerberührung ab:
1 |
float touchX = event.getX(); |
2 |
float touchY = event.getY(); |
Schritt 2
Mit dem Parameter MotionEvent der Methode onTouchEvent können wir auf bestimmte Berührungsereignisse reagieren. Die Aktionen, an denen wir interessiert sind, um das Zeichnen zu implementieren, sind down, move und up. Fügen Sie der Methode eine switch-Anweisung hinzu, um auf jede dieser Anweisungen zu antworten:
1 |
switch (event.getAction()) { |
2 |
case MotionEvent.ACTION_DOWN: |
3 |
drawPath.moveTo(touchX, touchY); |
4 |
break; |
5 |
case MotionEvent.ACTION_MOVE: |
6 |
drawPath.lineTo(touchX, touchY); |
7 |
break; |
8 |
case MotionEvent.ACTION_UP: |
9 |
drawCanvas.drawPath(drawPath, drawPaint); |
10 |
drawPath.reset(); |
11 |
break; |
12 |
default: |
13 |
return false; |
14 |
}
|
Nehmen Sie sich einen Moment Zeit, um sich diesen Code anzusehen. Wenn der Benutzer die Ansicht berührt, bewegen wir uns zu dieser Position, um mit dem Zeichnen zu beginnen. Wenn sie ihren Finger auf die Ansicht bewegen, zeichnen wir den Pfad zusammen mit ihrer Berührung. Wenn sie ihren Finger aus der Ansicht heben, zeichnen wir den Pfad und setzen ihn für den nächsten Zeichenvorgang zurück.
Schritt 3
Schließen Sie nach der switch-Anweisung die Methode ab, indem Sie die Ansicht ungültig machen und einen echten Wert zurückgeben:
1 |
invalidate(); |
2 |
return true; |
Durch den Aufruf von invalidate wird die onDraw-Methode ausgeführt.
3. Farben auswählen
Schritt 1
Lassen Sie uns nun die Möglichkeit implementieren, dass der Benutzer Farben aus der Palette auswählen kann. Fügen Sie in der Hauptaktivität der App die folgenden Importe hinzu:
1 |
import android.view.View; |
2 |
import android.widget.ImageButton; |
3 |
import android.widget.LinearLayout; |
Fügen Sie der Klasse die folgende Instanzvariable hinzu:
1 |
private DrawingView drawView; |
Das ist die Instanz der benutzerdefinierten Ansicht, die wir dem Layout hinzugefügt haben. In onCreate instanziieren Sie diese Variable nach dem vorhandenen Code, indem Sie einen Verweis darauf aus dem Layout abrufen:
1 |
drawView = (DrawingView)findViewById(R.id.drawing); |
Wir haben jetzt die Ansicht, die in der Aktivität angezeigt wird, in der die Methoden in der DrawingView-Klasse aufgerufen werden können.
Schritt 2
Wir haben die ursprüngliche Farbe der Zeichnung in der View-Klasse der Zeichnung festgelegt. Lassen Sie uns nun die Benutzeroberfläche so einrichten, dass sie diese widerspiegelt und verwaltet. Fügen Sie in der Hauptaktivitätsklasse eine weitere Instanzvariable hinzu, um die Schaltfläche für die Malfarbe in der Palette darzustellen:
1 |
private ImageButton currPaint; |
In onCreate möchten wir nun die erste Malfarbenschaltfläche im Palettenbereich abrufen, die zunächst ausgewählt werden soll. Rufen Sie zuerst das lineare Layout ab, in dem es enthalten ist:
1 |
LinearLayout paintLayout = (LinearLayout)findViewById(R.id.paint_colors); |
Holen Sie sich die erste Schaltfläche und speichern Sie sie als Instanzvariable:
1 |
currPaint = (ImageButton)paintLayout.getChildAt(0); |
Wir verwenden ein anderes Zeichenbild für die Schaltfläche, um anzuzeigen, dass es derzeit ausgewählt ist:
1 |
currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed)); |
Fügen Sie diese Datei jetzt den Drawables Ihrer App hinzu, geben Sie ihr den Namen "paint_pressed.xml" und geben Sie die folgende Form ein:
1 |
<layer-list xmlns:android="https://schemas.android.com/apk/res/android" > |
2 |
<item>
|
3 |
<shape android:shape="rectangle" > |
4 |
<stroke
|
5 |
android:width="4dp" |
6 |
android:color="#FF333333" /> |
7 |
|
8 |
<solid android:color="#00000000" /> |
9 |
|
10 |
<padding
|
11 |
android:bottom="0dp" |
12 |
android:left="0dp" |
13 |
android:right="0dp" |
14 |
android:top="0dp" /> |
15 |
</shape>
|
16 |
</item>
|
17 |
<item>
|
18 |
<shape xmlns:android="http://schemas.android.com/apk/res/android" > |
19 |
<stroke
|
20 |
android:width="4dp" |
21 |
android:color="#FF333333" /> |
22 |
|
23 |
<solid android:color="#00000000" /> |
24 |
|
25 |
<corners android:radius="10dp" /> |
26 |
</shape>
|
27 |
</item>
|
28 |
</layer-list>
|
Das ist der "paint.xml" sehr ähnlich. Zeichnung, die wir beim letzten Mal erstellt haben, jedoch mit einer dunkleren Farbe um die Farbe.
Schritt 3
Jetzt können wir den Benutzer Farben auswählen lassen. Bei der letzten Erstellung des Layouts haben wir ein onClick-Attribut für die Farbpalettenschaltflächen aufgelistet. Fügen Sie die Methode jetzt Ihrer Hauptaktivitätsklasse hinzu:
1 |
public void paintClicked(View view){ |
2 |
//use chosen color
|
3 |
}
|
Überprüfen Sie in dieser Methode zunächst, ob der Benutzer auf eine Farbe geklickt hat, die nicht die aktuell ausgewählte Farbe ist:
1 |
if(view!=currPaint){ |
2 |
//update color
|
3 |
}
|
Rufen Sie innerhalb des if-Blocks das Tag ab, das wir für jede Schaltfläche im Layout gesetzt haben, um die ausgewählte Farbe darzustellen:
1 |
ImageButton imgView = (ImageButton)view; |
2 |
String color = view.getTag().toString(); |
Wir müssen die benutzerdefinierte Ansichtsklasse verwenden, um die Farbe festzulegen. Wechseln Sie jetzt zur DrawingView-Klasse und fügen Sie die folgende Methode hinzu:
1 |
public void setColor(String newColor){ |
2 |
//set color
|
3 |
}
|
Beginnen Sie innerhalb der Methode mit der Ungültigmachung der Ansicht:
1 |
invalidate(); |
Als Nächstes analysieren und legen Sie die Farbe für das Zeichnen fest:
1 |
paintColor = Color.parseColor(newColor); |
2 |
drawPaint.setColor(paintColor); |
Rufen Sie in Ihrer Hauptaktivität in der paintClicked-Methode nach dem Abrufen des Farbetags die neue Methode für das benutzerdefinierte View-Objekt der Zeichnung auf:
1 |
drawView.setColor(color); |
Aktualisieren Sie nun die Benutzeroberfläche, um die neu ausgewählte Farbe wiederzugeben, und setzen Sie den vorherigen auf Normal zurück:
1 |
imgView.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed)); |
2 |
currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint)); |
3 |
currPaint=(ImageButton)view; |
Schlussfolgerung
Sie können jetzt die App ausführen und auf der Leinwand zeichnen, wobei Sie die Farben zum Zeichnen auswählen können. Sie sollten sehen, dass die Schaltflächen der Farbpalette die aktuell gewählte Farbe widerspiegeln. In diesem Tutorial haben wir uns mit den wichtigsten Funktionen einer beliebigen Berührung-Zeichnen-App für Android beschäftigt. Sie sollten jetzt die grundlegenden Fähigkeiten besitzen, um Ihre eigenen Zeichenfunktionen in anderen Apps zu implementieren. Im letzten Teil der Serie setzen wir das Löschen ein, wählen die Größe des Pinsels und des Radiergummis aus, speichern Zeichnungen und beginnen neue Zeichnungen.



