2D Graphik

  • 7 Antworten
  • Letztes Antwortdatum
N

note3

Ambitioniertes Mitglied
0
Hallo zusammen,

wer im neuen Jahr einen hebt, hat das alte gut überlebt.
In diesem Sinne Prost Neujahr.

Zu meinem Anliegen: ich will (erstmalig) eine Graphik erstellen,
dazu habe ich nach einem Tipp im Internet eine neue View-Klasse erstellt

Code:
public class Zeichnung extends View
{   private Paint paint;
    public Zeichnung(Context context, AttributeSet attrs)
    {  super(context);
       setPaintAttributes();
    }
    private void setPaintAttributes()
    {  ....
    }
    @Override
    public void onDraw(Canvas canvas)
    {  ...
    }
}
In der main_activity xml habe ich dann diese Klasse eingefügt.
Code:
<meine.packages.Zeichnung  
    android:id="@+id/z1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    ></meine.packages.Zeichnung>
Soweit funktioniert alles.
Jetzt will ich nach einem Button-Click die Zeichnung
neu erstellen, dabei verabschiedet sich aber die App.

Leider ist in meinem Buch kein Graphik-Kapitel vorhanden,
also habe ich probiert.

In der MainActivity stehen die Befehle

Code:
Zeichnung z1;
...
z1=(Zeichnung)findViewById(R.id.z1);
dann der Versuch:
@Override
Code:
public void onClick(View v) 
{   switch(v.getId())
    {  case R.id.btn1:
       z1.invalidate();
       // alternativ   z1.refreshDrawableState();
    }
}
Die Befehle werden angenommen,
aber die App verabschiedet sich bei dem Befehl z1.invalidate();

Wie kann man die Graphik neu erstellen?

Gruß
E.S.
 
Mit welcher Fehlermeldung verabschiedet sich die App denn?
Das wäre eigentlich das wichtigste zu wissen.
 
amfa schrieb:
Mit welcher Fehlermeldung verabschiedet sich die App denn?
Das wäre eigentlich das wichtigste zu wissen.

Habe gerade festgestellt, dass z1=null wird, dann kann es natürlich nicht gehen.
Suspekt war mir die Anweisung
z1=(Zeichnung)findViewById(R.id.z1);
schon, aber wie bekomme ich einen Zugriff auf den Bereich in den ich dann
zeichnen will?
 
Hmm also das mit findViewbyId zu machen ist schon der richtige Weg.

Du kannst natürlich auch mal probieren deinen CustomView programmatisch zu erzeugen

Zeichnung z1 = new Zeichnung();

und dann per AddView ins Layout einhängen.
Das alles erklärt aber noch nicht, warum du Null zurück bekommst - da muss noch woanders ein Fehler sein.
Hast du alle Konstruktoren im View kreiert ??

Code:
PS:   der Tipp mit dem programmatischen erzeugen, hilft eventl in so weit, das er Dir beim Erzeugen weitere Fehlermeldungen wirft und du so etwas besser debuggen kannst.



    public FieberKurve(Context context, AttributeSet attrs) {
        super(context, attrs);
        
        if(!isInEditMode()){
            init();
        }
    }

    public FieberKurve(Context context) {
        super(context);
       if(!isInEditMode()){
        init();
      }
Normalerweise ist auch die onDraw Methode im CustomView protected und nicht public. Diese Methode wird nicht direkt aufgerufen sondern über das setzen von invalidate. Der View ruft dann das onDraw selber auf.
 
  • Danke
Reaktionen: note3
killphil75 schrieb:
...
Zeichnung z1 = new Zeichnung();
Danke, allerdings muss man schreiben
Zeichnung z1 = new Zeichnung(this);

Allerdings wird mit dem Befehl
z1.invalidate();
in onClick() die Zeichnung nicht neu erstellt.
Was fehlt jetzt da noch?

Was mich außerdem verblüfft:
Die Zeichnung wird im Graphical Layout der xml Datei
sofort angezeigt. Das sieht mir nach einem Bild aus, das
einmal erzeugt und dann immer wieder angezeigt wird.
z1 ist dann ein Ochse, den man mit invalidate() ins Horn zwicken kann,
nur merkt er es nicht.
 
ja, ja der Context - Sorry den hatte ich vergessen.

Ok lass uns mal rekapitulieren - deine App stürzt nicht mehr ab ?

in onClick() die Zeichnung nicht neu erstellt.

Aus der Ferne ist das immer schwer zu raten. Aber wie sieht den deine onDraw in deinem Customview aus - bekommt die immer neue Werte zum Zeichnen ?
Wenn ja woher. Bau Dir doch mal Log Ausgaben in dem OnDraw bzw. in deinen Routinen wo vorher die Daten für den onDraw generiert werden ein.
Da kannst du prüfen, was wirklich aufgerufen wird.
 
Das Problom ist das Canvas.
Ich muss meinem Customview offensichtlich noch ein canvas übergeben.
Denn ich habe mir mal das canvas aus der onDraw-methode gemerkt
und mit diesem dann in der onClick der main_activity mein CustomView
aufgerufen:
z1.draw(canvas);
Durch Zufall stand vor diesem Aufruf ein
btn.setText(s);

Jetzt wird bei jedem Klick neu in das Button-Feld gezeichnet.

Ja und wie teile ich jetzt dem Customview ein canvas mit?
z1 = new Zeichnung(this) macht es nicht und
z1=(Zeichnung)findViewById(R.id.z1) geht nicht.
 
Ui ui ui böses Missverständnis, so wird das Nix.

Zum Verständnis -> dein CustomView ist ja ein eigenes Widget wie zum Beispiel ein Button, Schalter, Grafik was auch immer.
Die onDraw ist protected damit keiner von aussen drauf rumfummeln kann. Das Element verwaltet sich selber.

Dein Customview hat einen Canvas -> dieser wird automatisch erzeugt (ist ja eine Ableitung von View). Du kannst aber nur in der onDraw Methode darauf zugreifen - sprich alles was du verändern möchtest muss in dieser OnDraw oder in deinem View passieren.

(natürlich kannst Du Dir in deinem View auch selber noch einen Canvas erstellen, darauf rummalen und am Ende diesen auf den Canvas des CustomElementes kopieren)

d.h. um Einfluss zu nehmen, baust Du Dir public Methoden innerhalb deines CustomViews.

public coolGrafik(){

errechne_coole_Grafikwerte;
invalidate(); // sorgt für das Neuzeichnen
}

public setzeNeueTexte(String text1, String text2){

// setze Texte im Customelement

xachse = text1;
yachse = text2;

// und alles wieder neu zeichnen
invalidate();
}



protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

// hier zeichnen
canvas.drawText(xachse, 8, 25, paintMeinText);
canvas.drawText(yachse, 80, 25, paintMeinText);


// Werte holen und zu einer Grafik verarbeiten
canvas. vollzeichen
}


Hinweis:

zum Zeichnen brauchst du immer PaintObjekte. In einem Paintobjekt legst du die Farbe, Strichstärke ect. pp fest.

Solche Paintobjekte sollte man nicht ständig NEU im onDraw erzeugen, weil das die Performance bremst. Solche Sachen immer im onCreate des Customviews. bzw in deiner init() Routine erzeugen


Beispiel

Code:
        paintMeinText= new Paint();
        paintMeinText.setColor(0xFF777777);
        paintMeinText.setTextSize(16);
        paintMeinText.setAntiAlias(true);
        paintMeinText.setTextAlign(Align.LEFT);


Mal ein komplett Beispiel:

http://androidcookbook.com/Recipe.seam?recipeId=4491
 
Zurück
Oben Unten