Objekte aus dem Layout löschen

  • Antworten:5
Robbiani Renato
  • Forum-Beiträge: 615

05.07.2021, 19:53:33 via Website

Hallo zusammen

Ich kreiere ein Spiel welches verschieden farbige Quadrate auf den Bildschirm zeichnet. Mit einem Handler lege ich die Quadrate auf mein Layout. Diese Quadrate verschwinden nach 5 Sekunden wieder.

package ch.robbisoft.quadrate

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import java.util.*
import android.os.Handler
import android.os.Looper
import android.widget.*
import androidx.appcompat.app.AlertDialog
import kotlin.random.Random

class MainActivity : AppCompatActivity() {

// Initialisierungen
val farbeArray = intArrayOf(
    R.drawable.rot,
    R.drawable.gelb,
    R.drawable.gruen,
    R.drawable.blau,
    R.drawable.cyan,
    R.drawable.ocker,
    R.drawable.magenta,
    R.drawable.schwarz,
    R.drawable.weiss)

var flBreite : Int = 0
var flHoehe : Int = 0
var zeitStart : Double = 0.0
var punkte = 0
var spielAktiv = true
var meldung : AlertDialog.Builder? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    flBreite = resources.displayMetrics.widthPixels
    flHoehe = resources.displayMetrics.heightPixels

    meldung = AlertDialog.Builder(this)

    flGesamt.setOnClickListener {
        if (!spielAktiv){
            start()
        }
    }

    meldung!!.setTitle(getString(R.string.lbl_dlg_titel))
    meldung!!.setMessage(getString(R.string.lbl_dlg_text))
    meldung!!.setCancelable(false)
    meldung!!.setPositiveButton(getString(R.string.lbl_ja)) {_, _ ->
        punkte = 0
        zeitStart = 0.0

// var kinder = flGesamt.childCount
// for(i in 2 .. kinder){
// flGesamt.removeViewAt(i)
// }
start()
}
meldung!!.setNegativeButton(getString(R.string.lbl_nein)) {_, _ ->
finish()
}

    if(savedInstanceState != null){
        punkte = savedInstanceState.getInt("punkte", 0)
        zeitStart = savedInstanceState.getDouble("zeit", 0.0)
    }
    start()
}

private fun start(){
    tvPunkte.text = getString(R.string.lbl_punkt).format(punkte)
    //Zufällige Farbe beim Start
    var farbeZiel = farbeArray[Random.nextInt(farbeArray.size)]
    ivZiel.setImageResource(farbeZiel)
    var ziel = ivZiel
    ziel = ImageView(this@MainActivity)
    ziel.setImageResource(farbeZiel)
    val lp = FrameLayout.LayoutParams(
        LinearLayout.LayoutParams.WRAP_CONTENT,
        LinearLayout.LayoutParams.WRAP_CONTENT
    )
    ziel.layoutParams = lp
    flGesamt.addView(ziel)
    if( zeitStart < 1 ) {
        zeitStart = Calendar.getInstance().time.time.toDouble()
    }
    spielAktiv = true

    //Neues Quadrat erzeugen
    val neuHandler = Handler(Looper.getMainLooper())
    val neuObjekt = object : Runnable {
        override fun run() {
            val ivNeu = ImageView(this@MainActivity)
            val farbe = farbeArray[Random.nextInt(farbeArray.size)]
            ivNeu.tag = farbe
            ivNeu.setImageResource(farbe)

            val lp = FrameLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
            )
            lp.leftMargin = (Random.nextDouble(0.05, 0.8) * flBreite).toInt()
            lp.topMargin = (Random.nextDouble(0.05, 0.8) * flHoehe).toInt()
            ivNeu.layoutParams = lp
            flGesamt.addView(ivNeu)

            ivNeu.setOnClickListener {
                flGesamt.removeView(ivNeu)
                if (spielAktiv) {
                    punkte += if (ivNeu.tag == farbeZiel) 1 else -1
                    tvPunkte.text = getString(R.string.lbl_punkt).format(punkte)
                }
            }

            val loeschHandler = Handler(Looper.getMainLooper())
            val loeschObjekt = object : Runnable {
                override fun run() {
                    flGesamt.removeView(ivNeu)
                }
            }
            loeschHandler.postDelayed(loeschObjekt, 5000L)
            neuHandler.postDelayed(this, 500L)
        }
    }
    neuHandler.postDelayed(neuObjekt, 500L)

    //Zielfarbe ändern
    val zielHandler = Handler(Looper.getMainLooper())
    val zielObjekt = object : Runnable {
        override fun run() {
            val farbeZielAlt = farbeZiel
            while (farbeZielAlt == farbeZiel)
                farbeZiel = farbeArray[Random.nextInt(farbeArray.size)]
            flGesamt.removeView(ziel)
            ziel = ImageView(this@MainActivity)
            ziel.setImageResource(farbeZiel)
            val lp = FrameLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
            )
            ziel.layoutParams = lp
            flGesamt.addView(ziel)
            zielHandler.postDelayed(this, 5000L)
        }

    }
    zielHandler.postDelayed(zielObjekt, 5000L)

    //Zeitanzeige
    val zeitHandler = Handler(Looper.getMainLooper())
    val zeitObjekt = object : Runnable {
        override fun run() {
            val zeitAktuell = Calendar.getInstance().time.time
            val zeitDifferenz = zeitAktuell - zeitStart
            val zeitAusgabe = 60 - zeitDifferenz / 1000
            brZeit.progress = (180 / 60 * zeitAusgabe).toInt()
            if (zeitDifferenz > 60000L) {
                spielAktiv = false
                neuHandler.removeCallbacks(neuObjekt)
                zielHandler.removeCallbacks(zielObjekt)
                flGesamt.removeView(ziel)
                meldung!!.show()
            } else {
                zeitHandler.postDelayed(this, 1000L)
            }
        }
    }
    zeitHandler.postDelayed(zeitObjekt, 1000L)
}

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putInt("punkte", punkte)
    outState.putDouble("zeit", zeitStart)
}

}

Ist die Spieldauer abgelaufen bleiben die übriggebliebenen Quadrate noch maximal 5 Sekunden stehen. Gibt es eine Möglichkeit um mein Quadrate auf dem Layout zu finden und zu vernichten?

Gruss Renato

Kommentieren
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

06.07.2021, 16:20:22 via Website

Du kannst doch alle ImageViews auf deinem Layout finden und diese dann löschen.
Oder zusätzlich noch eine Liste mit "aktiven" Objekten führen

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Kommentieren
Robbiani Renato
  • Forum-Beiträge: 615

06.07.2021, 19:15:42 via Website

Ciao Pascal

Ja das geht. Ich mache es wie folgt:

var kinder = flGesamt.childCount
                for(i in 0 .. kinder){
                    var objekt = flGesamt.getChildAt(i)
                    if ( objekt) {
                        flGesamt.removeViewAt(i)
                    }
                }

Mein Problem ist, wie kann ich prüfen von welchem Type mein "objekt" ist. Denn ich will ja nur die ImageView löschen.

Gruss Renato

Hilfreich?
Kommentieren
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

08.07.2021, 09:08:48 via Website

Naja das geht auch:

if( objekt instanceof ImageView)...

Ist allerdings immer eher unschön das auf Instanz zu Prüfen.
Dann lieber eine Liste mit ImageViews führen.

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Kommentieren
Robbiani Renato
  • Forum-Beiträge: 615

09.07.2021, 19:57:52 via Website

Ich habe es wie folgt gelöst:

if (objekt::class == ImageView::class)

Das geht. Aber ich versuche mal die Variante von Rafael. Ich denke das geht ebenfalls.

Gruss Renato

Hilfreich?
Kommentieren