automatischer Farbwechsel

  • Hallo Leute,


    ich würde gerne einen Kreis erstellen, welcher ständig die Farbe wechselt. Solange bis ein Button geklickt wird.
    Die Erstellung eines Kreises ist kein Problem, der Farbwechsel an sich auch nicht - nur wird dies nicht angezeigt, wenn ich es beispielsweise in eine Schleife packe und laufen lassen.


    In meinem Kopf habe ich eine "Endlosschleife" welche die Farbe des Kreises ändert und der Benutzer dies auch sieht. Sobald er den Button drückt, hört diese "Endlosschleife" auf zu laufen. Wie kann man soetwas realisieren?
    Mir ist gerade die Idee von Threads gekommen, dazu habe ich leider noch kein Wissen. Ist dies der richtige Weg?


    Ich hoffe jemand hat einen guten Tipp für mich :)


    Danke

  • Hi,


    von Farbe wechseln und irgendwelchen Animationen hab ich keine Ahnung, dafür fehlt mir das Gefühl :D. Aber ohne Threads o.ä. gehts nicht, da sich die UI nicht aktualisiert, wenn du irgendwelche Endlosschleifen in den Main-Thread der App packst, da bist du schon auf dem richtigen Weg.


    Das absolute Grundgerüst

    Java
    Thread t = new Thread({
      public void run() {
         // Endlosschleife, die die Farbe wechselt
      }
    }); 
    t.start();


    dürfte relativ klar sein, denke ich. In der run-Methode packst du dann dein Endloses konstrukt rein und mit einem Thread.sleep kannst du immer wieder pausen einbauen.


    Wahrscheinlich meldet sich hier aber auch noch der ein oder andere, der vll. auch mal ein Game gebaut hat und somit etwas mehr Gefühl und Erfahrung mit solchen Animationen mit bringt ;)


    Gruß,
    matze

  • Danke für den Hinweis, ich habe es mir ja fast gedacht. Leider klappt der Versuch nicht, die Anwendung bricht mit einem Fehler ab.
    Ich habe in einer Subactivity einen Kreis, beim Klick auf einen Button soll dieser anfangen die Farbe zu wechseln.


    An dieser Stelle etwas Quellcode:


    Nachdem der Button geklickt wurde, soll der Thread gestartet werden, sobald es dazu kommt, stürzt das Programm sofort ab.
    Führe ich es nicht parallel aus, also wie folgt klappt alles:


    Kann mir jemand meinen Fehler beschreiben?
    Ich habe das Gefühl der Thread startet in der falschen Activity (im Menü vor dieser game-Activity), sprich er ist gar nicht am richtigen Ort, aber dies kann ja nicht sein oder?

  • Ich habe in einer Subactivity einen Kreis, beim Klick auf einen Button soll dieser anfangen die Farbe zu wechseln.


    Also dein Button und dein Kreis befinden sich in unterschiedlichen Activitys? Soweit ich weiß sind alle Elemente ausserhalb der gerade aktiven Activity null.
    Du könntest zum besseren Verständnis vll auch den Output vom LogCat anhängen.


    Gruß,
    matze

  • Oh nein, Button und Kreis befinden sich natürlich in einer Activity.
    Die Fehler entstehen bei der 1. Zeile, nehme ich diese weg bei der 2. Zeile im Folgenden:

    Java
    gameField.removeAllViews();
    gameField.addView(gameCircle);


    Wie zeichnet man etwas neu? .repaint() oder .refresh() existiert leider nicht. Gern würde ich daher das FrameLayout neu zeichnen, was ich nur angelegt habe, damit der Kreis einem kleinen Bereich zugeordnet ist.
    Der Kreis ist ein Canvas-Objekt. Ich ändere beim Kreis die Eigenschaft der Farbe, doch da dieser bereits gezeichnet ist sieht man dies natürlich nicht. Da der Kreis dem FrameLayout zugeordnet ist, würde ein neues zeichnen des Kreises dazu führen, dass alles korrekt ist.


    Mein Versuch war nun alle Views innerhalb des FrameLayout zu löschen und wieder diesen neuen View (den Canvas-Kreis) hinzuzufügen.


    //edit:
    Mir ist gerade eingefallen, dass ich das Canvas-Objekt je refreshen kann:

    Java
    gameCircle.refreshDrawableState();
    gameCircle.invalidate();


    Leider stützt das Programm bei invalidate() ab :(
    Wie macht man es richtig?

  • Hallo block_,
    eine richtige Fehlermeldung bekomme ich leider nicht :( Es steht nur da, das der Prozess beendet wird.


    meine Kreis-Klasse sieht wie folgt aus:


    Im Spiel wird der Kreis wie folgt erstellt:

    Java
    gameCircle = new Circle(this,
    								display.getWidth(),
    								display.getHeight(),
    								Circle.getColor());


    Nun möchte ich gern im Thread die Farbe wechseln:

    Java
    gameCircle.chanceColor(Circle.getColor());
    gameCircle.refreshDrawableState();


    getColor sollte natürlich nicht von außen aufrufbar sein, sondern nur private in der Kreis-Klasse selbst!

  • Hallo Steusi,


    Du darfst aus einem anderen Thread nichts an der UI ändern, das darf nur der UI-Thread, deswegen stürzts bei .invalidate() ab. Probier mal stattdessen .postInvalidate(), dies zeigt dem UI Thread an das er dein View neu zeichnen soll. Gibt auch andere Lösungen wie Activity.runOnUiThread() aber eigentlich sollte es so klappen.


    Gruss antifish

  • Danke antifish,


    ich verstehe - macht natürlich Sinn. Wenn es so läuft, würde mich eins noch brennend interessieren. Kann man in einem Thread auch auf ein View-Element zugreifen um zu prüfen, ob ein Button geklickt wurde als Beispiel?


    Muss ich eine Thread-Klasse erstellen, welche vom Thread erbt und dann überschreibe ich die run-Methode um ein View-Element zu übergeben oder gibt es einen Trick?

  • Danke antifish,


    ich verstehe - macht natürlich Sinn. Wenn es so läuft, würde mich eins noch brennend interessieren. Kann man in einem Thread auch auf ein View-Element zugreifen um zu prüfen, ob ein Button geklickt wurde als Beispiel?


    Muss ich eine Thread-Klasse erstellen, welche vom Thread erbt und dann überschreibe ich die run-Methode um ein View-Element zu übergeben oder gibt es einen Trick?

    Du kannst aus einem Thread auf ein View element zugreifen, solange du eine Refernez dazu hast.
    Allerdingst ist die Android UI ja Event basiert, also muss du nicht den Button abfragen ob er gedrückt ist, sonder der Button sagt dir wenn er gedrückt wird.
    Dazu kannst du einen "Listener" kreieren und beim Button setzen, somit weiss der Button wem er Bescheid sagen muss wenn er gedrückt wird.
    In Code für dein Beispiel etwas so:


    Button button = (Button)findViewById(R.id.button1);
    button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
    changeColor.stop();
    }
    });

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!