Java [Android] Wie eigene (primitive) android.widget, wie z.B. TextView design

T

Tersus

Gast
Guten Abend,

ich möchte ein eigenes grafisches Element zur Bedienung der Oberfläche gestalten. Wie gehe ich dabei vor? Ich erweitere eine View und nutze dessen onDraw(...) Methode zum Zeichnen, gut.

Nun gibt es da ein Problem:

Ich kann nicht die Länge/Breite des mit Canvas gezeichneten Rechtecks angeben, sondern muss Start- und Stopkoordinaten angeben. Das hat zur Folge, dass, egal welchem Layout ich meine View zuweise, die Grafik immer an den von mir gewählten Koordinaten erscheint ... . Wie kann ich sie in Abhängigkeit zum Layout platzieren? Also Ohne fixe Koordinaten.

Vielen Dank für die Hilfe!
 
Tersus schrieb:
Ich kann nicht die Länge/Breite des mit Canvas gezeichneten Rechtecks angeben, sondern muss Start- und Stopkoordinaten angeben.

Wieso musst Du das ? Verstehe ich nicht so ganz. Klar kannst Du Länge und Breite des Canvas verwenden. Allerdings funtioniert das mit den Canvas-Extends nicht auf allen Android-Versionnen gleich, der Canvas kann auch größer als die View sein. Nimm die Breite/Höhe der View, dann klappt das auch.

Das hat zur Folge, dass, egal welchem Layout ich meine View zuweise, die Grafik immer an den von mir gewählten Koordinaten erscheint ... . Wie kann ich sie in Abhängigkeit zum Layout platzieren? Also Ohne fixe Koordinaten.

Deine Beschreibung ist wie gesagt, nicht ganz eindeutig, aber wenn Du z.B. einen Kreis zeichnen willst, der in der View zentriert ist und von der View umschlossen wird, ganz unabhängig davon, wie die View im Layout dimensioniert wurde, dann geht das ganz einfach so:

Code:
protected void onDraw( Canvas canvas ) {
    canvas.save();

    float width = this.getWidth();
    float height = this.getHeight();
    float radius = Math.min(width/2f, height/2f);
    float cx = width/2f;
    float cy = height/2f;

    canvas.drawCircle( cx, cy, radius, this.mPaint );
    
    canvas.restore();
}

Die Größe berechnest Du aber besser nicht in onDraw(), sondern in onSizeChanged():
1. Um Berechnungen nicht unnötig immer wieder neu zu machen
2. Um nicht unnötig Objekte im onDraw() zu allokieren (z.B. Rect, RectF)

Wenn Du im Layout mit "wrap_content" arbeiten willst, musst Du natürlich auch onMeasure() überladen, ansonsten verhält sich "wrap_content" wie "match_parent". Absolute Layoutgrößen, Weights innerhalb linearer Layouts oder Bezüge innerhalb realtiver Layouts funktionieren natürlich trotzdem.

Wie es in allen Einzelheiten funktioniert, kannst Du doch hier nachlesen, in den SDK Samples findet sich auch das einen oder andere Nützliche:
http://developer.android.com/training/custom-views/index.html
 
Zuletzt bearbeitet:
Erstmal vielen Dank für Deine Unterstützung!

Das habe ich aber dennoch nicht ganz verstanden. Wenn ich die von Dir gebastelte View, welche einen Kreis nach dessen Maßen zeichnet, verwende und sie meinem LinearLayout zufüge, so nimmt diese View den gesamten Platz des Bildschirms ein. Sie wird vom Layout vermutlich automatisch auf die maximale Größe gezogen. Weitere Elemente, die nach der selbstgebauten View dem LinearLayout zugefügt werden, wie ein simpler Button, werden auf dem Bildschirm gar nicht mehr angezeigt.

Die selbstgebastelte View soll also nur maximal so groß sein, wie auch das mit Canvas Gezeichnete.

Die View sollte also nur so hoch sein, wie der Kreis, sei er schwarz auf weißem Hintergrund, in dem Falle breit ist.

Irgendwie doch schwierig?
 
Das hatte ich doch geschrieben: Wenn Du nicht onMeasure() überlädst und entsprechend implementierst dann verhält sich ein "wrap_content" im Layout für Deine View genauso wie ein "match_parent". Das ist das, was Du jetzt siehst.

Setzt Du für die View im Layout aber eine feste Größe oder verteilst die einzelnen Views im linearen Layout indem Du andoird:layout_weight setzt, dann funktioniert das auch ohne.

Du hast doch nur zwei Möglichkeiten:
1. Die Größe der View legst Du im Layout fest, im onDraw() orientierst Du dich dann an der aktuellen Größe
2. Im Layout setzt Du "wrap_content", dann muss die View natürlich selbst bestimmen, wie groß sie denn sein soll. "wrap_content" bestimmt ja, dass dieView selbst Auskunft über ihre Größe gibt und das musst Du natürlich implementieren -> onMeasure()

Was willst Du denn genau ? Einen Kreis zeichnen, der z.B. immer einen Radius von 200 Px oder 200dp hat und dann soll sich die Größe der View bei "wrap_content" entsprechend anpassen ? Oder willst Du dass deine View eine durch das Layout vorgegebene Größe voll ausfüllt ?

Lies Dir doch mal die Doku durch, da ist wirklich alles haarklein beschrieben und eine Sample-Implementierung ist auch noch dabei.
 
Ich habe gefunden, wonach ich suchte! Ja, die onMeasure() Methode war es und ich danke dir vielmals für Deine Unterstützung! :)
 

Ähnliche Themen

T
Antworten
2
Aufrufe
1.160
T
Zurück
Oben