Bilder eine gewisse Zeit anzeigen und dann wechseln

  • Antworten:21
  • Bentwortet
TheStephan
  • Forum-Beiträge: 14

24.02.2019, 11:22:37 via Website

Hallo Leute, ich brauche dringend eure Hilfe!!

Ich habe in meiner App eine unbestimmte Anzahl an Checkboxen hinterlegt. Zu jeder Checkbox gehört ein Bild. Nun möchte ich, je nach Auswahl der Checkboxen, nach dem Betätigen eines Buttons dass die Bilder in der Ausgewählten Reihenfolge hintereinander für eine bestimmte Zeit einzeln angezeigt werden.
Dass die Bilder hintereinander angezeigt werden habe ich schon mal hinbekommen, nur dass sie für eine bistimmte Zeit angezeigt werden noch nicht. Ich hoffe jemand kann mir Helfen. Anbei der bisherige Code:

    @Override
    public void onClick(View v) {

            if (CB1.isChecked())
            {
                design.setVisibility(pic1.VISIBLE);
            }
        if (CB2.isChecked()) {
            buy.setVisibility(pic2.VISIBLE);
        }
    }
}

Grüße Stephan

— geändert am 24.02.2019, 11:32:14 durch Moderator

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

24.02.2019, 19:16:42 via Website

Könnte so aussehen:
(code ist nicht getestet und kann fehler enthalten, sollte dir aber die Methodeik erklären)

public class MainActivity extends AppCompatActivity implements View.OnClickListener {


        Button button;        
        Map<CheckBox,ImageView> boxMap = new ArrayList<CheckBox,ImageView>();


        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            //@ToDo: Die CBs wenn die dynamisch sicht vlt auch per Schleife genieren und dem Layout hinzufügen, spart Code 
           Checkbox CB1 = (CheckBox) findViewById(R.id.CB1);
           Checkbox CB2 = (CheckBox) findViewById(R.id.CB2);
           Checkbox CB3 = (CheckBox) findViewById(R.id.CB3);
           Button  button = (Button) findViewById(R.id.button);
           ImageView pic1 = (ImageView) findViewById(R.id.pic1);
           ImageView pic2 = (ImageView) findViewById(R.id.pic2);
           ImageView pic3 = (ImageView) findViewById(R.id.pic3);

            pic1.setVisibility(pic1.GONE);
            pic2.setVisibility(pic2.GONE);
            pic3.setVisibility(pic2.GONE);
            button.setOnClickListener(this);

            //Add elements to Map
            boxMap.put(CB1,pic1);
            boxMap.put(CB2,pic2);
            boxMap.put(CB3,pic3);

        }
        @Override
        public void onClick(View v) {
           Handler handler = new Handler();

                int count =0;
           for (Map.Entry<CheckBox, ImageView> entry : boxMap.entrySet()) //for all CheckBoxes
            {
                CheckBox currentBox = entry.getKey();
                ImageView currentImage = entry.getValue();

                if(currentBox.isChecked()){
                    if(count==0){ //First checked Box
                         currentImage.setVisibility(View.VISIBLE);       
                    }
                    else{

                        handler.postDelayed(new Runnable(){
                            public void run(){

                                //Solage du in den 2Sek die Boxen nicht mehr änderst:
                              currentImage.setVisibility(View.VISIBLE);

                            }
                        },counter*2000); //2 sek verzögern, mal Anzahl der Iterationsschritte

                    }
                    count++; //zähler erhöhen
                }
            }

            }
    }

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

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

24.02.2019, 11:30:39 via App

Hallo TheStephan,

du musst schon etwas mehr von deinem Code zeigen.
Ich würde die CheckBoxen als Liste speichern und die nicht einzeln vom Layout lesen.
Dann kannst du durch die Liste Iterieren und dir die Bilder rausziehen und nacheinander eine bestimmte Zeit anzeigen

Edit: Und was sind Design und buy und warum so komische Visible Commands?

— geändert am 24.02.2019, 11:31:41

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

Hilfreich?
TheStephan
Kommentieren
TheStephan
  • Forum-Beiträge: 14

24.02.2019, 11:37:33 via Website

Erstmals vielen Dank für deine schelle Antwort. Durch das visible mache ich die Bilder hintereinander sichtbar, nur die Pausenzeit dazwischen fehlt mir noch zur korrekten Anzeige. Anbei nochmals der gesamte code.

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    CheckBox CB1, CB2;
    Button button;
    ImageView pic1, pic2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        CB1 = (CheckBox) findViewById(R.id.CB1);
        CB2 = (CheckBox) findViewById(R.id.CB2);
        button = (Button) findViewById(R.id.button);
        pic1 = (ImageView) findViewById(R.id.pic1);
        pic2 = (ImageView) findViewById(R.id.pic2);

        pic1.setVisibility(pic1.GONE);
        pic2.setVisibility(pic2.GONE);
        button.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
           if (CB1.isChecked())
            {
                pic1.setVisibility(pic1.VISIBLE);
            }
        if (CB2.isChecked()) {
            pic2.setVisibility(pic2.VISIBLE);
        }
    }
}
Hilfreich?
Kommentieren
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

24.02.2019, 11:55:09 via Website

Hallo Stephan,

du hattest von einer unbestimmten Anzahl gesprochen, dein Beispiel befasst sich aber mir einer festen Anzahl von 2 CheckBoxen. Das ist nur mit etwas Aufwand auf eine belibige Anzahl erweiterbar.

Aber zum Code:

du musst die 2. Visible Anweisung einfach verzögern, z.b. mit Handler#postDelayed:

Hander handler = new Handler();
handler.postDelayed(new Runnable(){ 
public void run(){
        if (CB2.isChecked()) {
            pic2.setVisibility(pic2.VISIBLE);
        }
}
},5000); //für 5 sek

Edit: Die View#VISIBLE ist eine Konstante, daher nach Konvention auch mittels Klasse anspechen:

pic2.setVisibility(View.VISIBLE);

gibt einen etwas besseren Code style ab.

— geändert am 24.02.2019, 11:56:31

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

Hilfreich?
TheStephanGelöschter Account
Kommentieren
Gelöschter Account
  • Forum-Beiträge: 79

24.02.2019, 12:02:20 via Website

Hi TheStephan,

was meinst du mit "Dass die Bilder hintereinander angezeigt werden habe ich schon mal hinbekommen"? So, wie der Code aussieht, werden, wenn beide Checkboxen aktiviert sind, auch direkt beide Bilder angezeigt, wenn man den Button drückt.

Das sie nur eine bestimmte Zeit eingezeigt werden sollen, könnte man mit einem Timer lösen, der die Visiblity wieder auf GONE stellt und beim Click auf den Button gestartet wird.

PS: Anstatt deine pic-Objekte auch im setVisibility-Command zu nutzen kannst du da auch "View.VISIBLE" und "View.GONE" schreiben. Das macht aus objektorientierter Sicht viel mehr Sinn. ^^

Hilfreich?
Pascal P.
Kommentieren
TheStephan
  • Forum-Beiträge: 14

24.02.2019, 13:21:30 via Website

Mit 2 Checkboxen funktionierts wunderbar, aber wenn ich eine dritte hinzufüge, und checkbox 1 und 3 Auswähle dann wird die erste angezeigt und die Dritte jedoch nicht.

— geändert am 24.02.2019, 13:51:49

Hilfreich?
Kommentieren
TheStephan
  • Forum-Beiträge: 14

24.02.2019, 13:24:00 via Website

Ja genau, die Bilder werden direkt hintereinander angezeigt, nur möchte ich halt dazischen eine Pause haben

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

24.02.2019, 15:12:44 via App

Wie sieht dein Code mit 3 Checkboxen aus?
Für das 3. Bild darfst du den Timer/Delay erst starten wenn das zweite Bild angezeigt wird

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

Hilfreich?
Kommentieren
TheStephan
  • Forum-Beiträge: 14

24.02.2019, 15:52:11 via Website

Wenn ich alle checkboxen anklicke, dann läuft mein Programm wie es soll.
Wenn ich nur Checkbox 3 anklicke, wird nichts angezeit.
Wenn ich checkbox 2 und 3 angeklickt habe, dann stimmt der Ablauf nur dass ich dann vor Bild 2 kein Delay haben möchte sondern dass es direkt angezegt wird.
Anbei noch der Code:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    CheckBox CB1, CB2, CB3;
    Button button;
    ImageView pic1, pic2, pic3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        CB1 = (CheckBox) findViewById(R.id.CB1);
        CB2 = (CheckBox) findViewById(R.id.CB2);
        CB3 = (CheckBox) findViewById(R.id.CB3);
        button = (Button) findViewById(R.id.button);
        pic1 = (ImageView) findViewById(R.id.pic1);
        pic2 = (ImageView) findViewById(R.id.pic2);
        pic3 = (ImageView) findViewById(R.id.pic3);

        pic1.setVisibility(pic1.GONE);
        pic2.setVisibility(pic2.GONE);
        pic3.setVisibility(pic2.GONE);
        button.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
       Handler handler = new Handler();


       if (CB1.isChecked()) {
           pic1.setVisibility(pic1.VISIBLE);
       }

        handler.postDelayed(new Runnable(){
            public void run(){
                if (CB2.isChecked()) {
                    pic2.setVisibility(pic2.VISIBLE);
                }
            }
        },2000); //für 5 sek

        handler.postDelayed(new Runnable(){
            public void run(){
                if (CB3.isChecked()) {
                    pic3.setVisibility(pic3.VISIBLE);
                }
            }
        },4000); //für 5 sek
        }
}
Hilfreich?
Kommentieren
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

24.02.2019, 17:08:22 via Website

Das funktioniert mir der expliziten deklaration für die CheckBoxen nicht.
Du musst diese in eine List oder Array packen und dann darüber iterieren, dann kannst du sowas machen.

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

Hilfreich?
TheStephan
Kommentieren
TheStephan
  • Forum-Beiträge: 14

24.02.2019, 18:50:57 via Website

Ok danke erst mal für deine Hilfe. Hättest du denn einen Ansatz wie ich dies lösen könnt?

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

24.02.2019, 19:16:42 via Website

Könnte so aussehen:
(code ist nicht getestet und kann fehler enthalten, sollte dir aber die Methodeik erklären)

public class MainActivity extends AppCompatActivity implements View.OnClickListener {


        Button button;        
        Map<CheckBox,ImageView> boxMap = new ArrayList<CheckBox,ImageView>();


        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            //@ToDo: Die CBs wenn die dynamisch sicht vlt auch per Schleife genieren und dem Layout hinzufügen, spart Code 
           Checkbox CB1 = (CheckBox) findViewById(R.id.CB1);
           Checkbox CB2 = (CheckBox) findViewById(R.id.CB2);
           Checkbox CB3 = (CheckBox) findViewById(R.id.CB3);
           Button  button = (Button) findViewById(R.id.button);
           ImageView pic1 = (ImageView) findViewById(R.id.pic1);
           ImageView pic2 = (ImageView) findViewById(R.id.pic2);
           ImageView pic3 = (ImageView) findViewById(R.id.pic3);

            pic1.setVisibility(pic1.GONE);
            pic2.setVisibility(pic2.GONE);
            pic3.setVisibility(pic2.GONE);
            button.setOnClickListener(this);

            //Add elements to Map
            boxMap.put(CB1,pic1);
            boxMap.put(CB2,pic2);
            boxMap.put(CB3,pic3);

        }
        @Override
        public void onClick(View v) {
           Handler handler = new Handler();

                int count =0;
           for (Map.Entry<CheckBox, ImageView> entry : boxMap.entrySet()) //for all CheckBoxes
            {
                CheckBox currentBox = entry.getKey();
                ImageView currentImage = entry.getValue();

                if(currentBox.isChecked()){
                    if(count==0){ //First checked Box
                         currentImage.setVisibility(View.VISIBLE);       
                    }
                    else{

                        handler.postDelayed(new Runnable(){
                            public void run(){

                                //Solage du in den 2Sek die Boxen nicht mehr änderst:
                              currentImage.setVisibility(View.VISIBLE);

                            }
                        },counter*2000); //2 sek verzögern, mal Anzahl der Iterationsschritte

                    }
                    count++; //zähler erhöhen
                }
            }

            }
    }

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

Hilfreich?
TheStephan
Kommentieren
TheStephan
  • Forum-Beiträge: 14

24.02.2019, 20:13:08 via Website

Den einzige Fehler den er noch bemängelt ist hier:

Map boxMap = new ArrayList();

Grund: wrong type of number arguments: 2; required 1

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

24.02.2019, 20:23:32 via App

Naja hier könnte dir auffallen das eine ArrayList nicht auf eine Map passt.

Da musst du schon eine HashMap nehmen:
=new HashMap<CheckBox,ImageView>()

Evtl. fehlen dur auch teilweise Java Grundlagen, daher ist das für ich mühsam.
erst nochmal plain Java anschauen und damit rumspielen.

— geändert am 24.02.2019, 20:25:12

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

Hilfreich?
TheStephanGelöschter Account
Kommentieren
TheStephan
  • Forum-Beiträge: 14

24.02.2019, 20:57:14 via Website

So der code ist nun Fehlerfrei

Alle CB ausgewählt: Manchmal funktioniert es, manchmal werden Bild 1 und 3 gleichzeitig und Bild 2 verspätet angezeigt
Nur CB3: nichts passiert
CB2 und CB3: Nach einer Delay time wird nur Bild 2 angezeigt
CB1 und CB3: Manchmal funktioniert es, manchmal allerdings werden nach einer delaytime beide Bilder gleichzeitig angezeigt

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

24.02.2019, 21:22:50 via App

Setze mal den "counter++;"
2 Zeilen höher dass die geschweifte Klammer dahinter zu geht.
Aber Code debuggen, ob eigenen oder Fremden solltest du auch lernen.
Verstehst du überhaupt was der Code tut?

— geändert am 24.02.2019, 21:23:16

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

Hilfreich?
Gelöschter Account
Kommentieren
TheStephan
  • Forum-Beiträge: 14

25.02.2019, 14:23:58 via Website

Ja Code habe ich verstanden, beim debuggen werden die Bilder leider nicht angezeigt jedoch werden die Schleifen korrekt aufgerufen. Kann es vlt damit zusammenhängen dass ich currentImage im else als final deklarieren musste? Ansonsten wird folgender Fehler ausgegeben: variable "currentImage" is accessed from within inner class, needs to be declared final

Hilfreich?
Kommentieren
Gelöschter Account
  • Forum-Beiträge: 79

25.02.2019, 15:43:02 via Website

Wenn du "currentImage" im Else-Block nochmal deklarieren musstest, dann ist wahrscheinlich irgendwo eine geschweifte Klammer verrutscht, oder so.
Falls du meinst, das du es oben als "final" deklarieren musstest, damit die Meldung nicht im Else-Block kommt, dann macht das soweit ich das sehe Sinn, weil es ja in der neuen Runnable benutzt wird.

Post am besten nochmal den Code, wie er jetzt bei dir mit den Änderungen aussieht.

Hilfreich?
Kommentieren
TheStephan
  • Forum-Beiträge: 14

25.02.2019, 15:45:37 via Website

Anbei der Code:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

Button button;

HashMap<CheckBox, ImageView> boxMap = new HashMap<CheckBox, ImageView>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //@ToDo: Die CBs wenn die dynamisch sicht vlt auch per Schleife genieren und dem Layout hinzufügen, spart Code
    CheckBox CB1 = (CheckBox) findViewById(R.id.CB1);
    CheckBox CB2 = (CheckBox) findViewById(R.id.CB2);
    CheckBox CB3 = (CheckBox) findViewById(R.id.CB3);
    Button  button = (Button) findViewById(R.id.button);
    ImageView pic1 = (ImageView) findViewById(R.id.pic1);
    ImageView pic2 = (ImageView) findViewById(R.id.pic2);
    ImageView pic3 = (ImageView) findViewById(R.id.pic3);

    pic1.setVisibility(pic1.GONE);
    pic2.setVisibility(pic2.GONE);
    pic3.setVisibility(pic3.GONE);
    button.setOnClickListener(this);

    //Add elements to Map
    boxMap.put(CB1,pic1);
    boxMap.put(CB2,pic2);
    boxMap.put(CB3,pic3);

}
@Override
public void onClick(View v) {
    Handler handler = new Handler();

    int count =0;
    for (HashMap.Entry<CheckBox, ImageView> entry : boxMap.entrySet()) //for all CheckBoxes
    {
        CheckBox currentBox = entry.getKey();
        final ImageView currentImage = entry.getValue();

        if(currentBox.isChecked()){
            if(count==0){ //First checked Box
                currentImage.setVisibility(View.VISIBLE);
            }
            else{
                handler.postDelayed(new Runnable(){
                    public void run(){
                        //Solage du in den 2Sek die Boxen nicht mehr änderst:
                        currentImage.setVisibility(View.VISIBLE);
                    }
                },count*2000); //2 sek verzögern, mal Anzahl der Iterationsschritte
            }
            count++;
        }

    }

}

}

Hilfreich?
Kommentieren
Gelöschter Account
  • Forum-Beiträge: 79

25.02.2019, 16:16:08 via Website

Hmm, so kann ich da jetzt nichts entdecken, was so ein Verhalten verursachen könnte, wie du es beschreibst.

Was mir gerade nur fehlt:
Die Bilder werden nur in der "onCreate" auf visibility = gone gestellt. Also eigentlich dürfte der Button, wenn überhaupt, auch nur ein einziges Mal wirklich richtig funktionieren, weil die Bilder danach ja schon sichtbar sind.

Hilfreich?
Kommentieren
TheStephan
  • Forum-Beiträge: 14

25.02.2019, 16:22:06 via Website

Ja die App funktioniert auch nur einmal, danach muss sie neu geöffnet werden. Was mir jedoch auch komisch vorkommt, dass die Ausgabe nicht immer dieselbe ist obwohl sich am Code ja nichts ändert...

Hilfreich?
Kommentieren
TheStephan
  • Forum-Beiträge: 14

26.02.2019, 14:57:48 via Website

Das Problem mit der Reihenfolge habe ich mittels einer LinkedHashMap gelöst. Füge ich ein viertes Bild hinzu, funktioniert der Code wie er soll. Werde es nun noch mit einer höheren Anzahl versuchen. In diesem Sinn vielen Dank für die Hilfe!!

Hilfreich?
Kommentieren