ListView Item durchstreichen erst nach paar Clicks

  • 5 Antworten
  • Letztes Antwortdatum
1

123thomas

Fortgeschrittenes Mitglied
44
Hallo Leute,

ich habe ein Problem bei dem ich nicht weiterkomme.

Bei meiner aktuellen App habe ich ein ListView, in welches ein Eintrag bei einem OnItemLongclick durchgestrichen werden soll und bei einem weiteren langen Click wieder zurückgesetzt werden sollte.

Das Problem ist folgendes: Wenn ich nun die App auf dem Handy starte und ein Eintrag lange Clicke, dann streicht der den Eintrag nur für eine sehr kurze Zeit durch. Danach ist der Text wieder nicht durchgestrichen. Dann muss ich erst ein paar lange Clicks ausführen bis er das durchstreichen "behält".

Leider ist es immer unterschiedlich wie oft ich einen Eintrag mit langen Clicks beaufschlagen muss bis er es komplett durchstreicht.

Der gesamte Code würde hier den Rahmen sprengen, daher liefere ich hier einen Teilcode. Falls ihr mehr für die Fehlersuche benötigt dann schreibt mir bitte.

Die Methode erstelleListe() wird alle 500ms von einem Timer ausgeführt.

Code:
    //ArrayList die die Daten enthült als HashMaps um es in den Listview zu übertragen
    ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
   
    //SimpleAdapter der die Daten in das List View überträgt
    private SimpleAdapter sa;
   
       
    public void erstelleListe()
    {

        //nur Liste erstellen wenn nicht gerade gelöscht oder erstellt wird
        if(!Variablen.SQLLöschenundErstelleninArbeit && !Variablen.LadeEinträge && !Variablen.LöscheEinträge && !Variablen.SpeicherEintrag && !Variablen.TrageEinträgeEin)
        {
            Variablen.checkeEinträge();
       
            //Liste leeren
            list.clear();
           
            //HashMap links each line of data to the correct TextView
            HashMap<String,String> item;
            for(int i=0;i<Variablen.cPosition;i++){
              item = new HashMap<String,String>();
              item.put( "line1", Variablen.getGegenstandarray()[i]);
              item.put( "line2", Variablen.getAnzahlarray()[i]);
              item.containsKey(Variablen.getPositionen()[i]);
              list.add( item );
            }

            //durchstreichen wenn strike gesetzt
            for(int i =0; i<100;i++)
            {
                if(Variablen.strikearray[i]) {
                    //dynamisch durchstreichen
                    TextView item5 = (TextView) getViewByPosition(i, listview).findViewById(R.id.line_a);
                    //item5.setPaintFlags(Paint.STRIKE_THRU_TEXT_FLAG);
                    item5.setPaintFlags(item5.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
                    TextView item6 = (TextView) getViewByPosition(i, listview).findViewById(R.id.line_b);
                    //item6.setPaintFlags(Paint.STRIKE_THRU_TEXT_FLAG);
                    item6.setPaintFlags(item6.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
                    Log.d("Streiche","Eintrag Nummer: " + i);
                }

            }
           
            sa = new SimpleAdapter(this, list, R.layout.listview_two_lines,  new String[] { "line1","line2" },   new int[] {R.id.line_a, R.id.line_b});
           
            listview.setAdapter(sa);

            listview.setOnItemClickListener(new OnItemClickListener() {

                @Override
                public void onItemClick(AdapterView<?> parent, View view,
                                        int position, long id)
                {
                        //Wenn das die Position ist dann
                        Variablen.aktuellePosition = position + 1;
                        //showToast(String.valueOf(position));

                        //Erstelle eine instanz des PopupMenus
                        PopupMenu popup = new PopupMenu(MainActivity.this, view);
                        //hole das XML und erstelle ein Menü
                        popup.getMenuInflater().inflate(R.menu.popup_item, popup.getMenu());

                        //erstelle ein OnClickListener auf den Optionen
                        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                            public boolean onMenuItemClick(MenuItem item) {
                                Toast.makeText(MainActivity.this, "Ups, da ist etwas schief gelaufen!", Toast.LENGTH_SHORT).show();

                                return true;
                            }
                        });
                        Popupmenugeschlossen = false;
                        popup.show();
                    



                }

            });

            listview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
                    Log.d("Langer Click", "auf das item");
                    if(Variablen.strikearray[i] == false) {
                        //Item durchstreichen
                        TextView item1 = (TextView) getViewByPosition(i,listview).findViewById(R.id.line_a);
                        item1.setPaintFlags(item1.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
                        TextView item2 = (TextView) getViewByPosition(i,listview).findViewById(R.id.line_b);
                        item2.setPaintFlags(item2.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
                        //durchstreichen eintragen
                        Variablen.strikearray[i] = true;
                    }
                    else
                    {
                        //Item nicht mehr durchstreichen
                        TextView item3 = (TextView) getViewByPosition(i,listview).findViewById(R.id.line_a);
                        item3.setPaintFlags(item3.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
                        TextView item4 = (TextView) getViewByPosition(i,listview).findViewById(R.id.line_b);
                        item4.setPaintFlags(item4.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
                        //durchstreichen austragen
                        Variablen.strikearray[i] = false;
                    }
                    return true;
                }
            });


            //Wenn Liste das erstemal erstellt ist dann Dialog beenden
            if(Dialogbeenden)
            {
                pDialog.dismiss();
                Dialogbeenden = false;
            }
        }
        else
        {
            String temp = "";
            if(Variablen.SQLLöschenundErstelleninArbeit)
            {
                temp = "Variablen.SQLLöschenundErstelleninArbeit";
            }
            if(Variablen.LadeEinträge)
            {
                temp += ", Variablen.LadeEinträge";
            }
            if(Variablen.LöscheEinträge)
            {
                temp += ", Variablen.LöscheEinträge";
            }
            if(Variablen.SpeicherEintrag)
            {
                temp += ", Variablen.SpeicherEintrag";
            }
            if(Variablen.TrageEinträgeEin)
            {
                temp += ", Variablen.TrageEinträgeEin";
            }
            Log.d("erstelleListe()", "Lösch- oder Eintragevorgang läuft noch:" + temp);
        }
    }

Ich bin für jeden Tip oder Anhaltspunkt dankbar. Für die Lösung natürlich um so mehr ;-)

Mit freundlichen Grüßen
Thomas
 
123thomas schrieb:
Die Methode erstelleListe() wird alle 500ms von einem Timer ausgeführt.
Sowas hab ich noch nie gesehen .. das kann nur zu Problemen führen!
Erstelle nen eigenen Adapter für deine ListView, guck dir mal den ArrayAdapter oder BaseAdapter an. Dann kannste mit notifyDataSetChanged "bescheid geben", wenn du neue Daten hast, dann wird deine Liste mit den neuen Daten geladen.
EDIT: Ginge sicher auch mit dem SimpleAdapter, aber so viel Arbeit ist es net ne weitere Klasse für den Adapter zu erstellen und der Code wird dadurch auch gleich viel sauberer :)
 
  • Danke
Reaktionen: 123thomas
Kann mich nur @burgerohnealles anschließen. Ein Timer ist keine gute Idee. So erstellst du alle 500ms die komplette Liste neu. Wenn jemand darin scrollt, wird er nicht froh sein, dass die Liste andauert neu gezeichnet wird. Im schlimmsten Fall kann es vorkommen, das die Methode schneller aufgerufen wird, als ein kompletter Durchlauf der Methode dauert. Auch braucht ein Longtouch eine bestimmte Zeit,bevor er ausgelöst wird. Wenn du vorher die Liste neu zeichnest, wird der Longtouch nicht augelöst.



Noch etwas zum Programmierstil. Manchmal fangen deine Methoden mit einen Großbuchstaben an (in Java werden die Methoden normalerweise klein geschrieben). Es erschwert die Lesbarkeit des Codes, wenn man sich an die allgemeinen Gepflogenheiten hält.


Code Style Guidelines for Contributors | Android Open Source Project
 
  • Danke
Reaktionen: 123thomas
Danke für die Tipps. Werde es dann mal in den nächsten Tagen es in einen ArrayAdapter umsetzen.

@markus.tullius Ich kann keine Methode finden mit einem großen Anfangsbuchstaben. Kannst du ein konkretes Beispiel nennen?

(Ich bin nur Hobby Programmierer daher habe ich wenig Ahnung vom Programmierstil)
 
@123thomas Sorry, Asche auf meinen Haupt. ;(

Wer zu schnell liest, der gehört bestraft. ;) "Variablen.SQLLöschenundErstelleninArbeit" ist ein String.

Zum Nachschlagen für dein Problem:
Using lists in Android (ListView) - Tutorial
 
Danke

hat etwas gedauert aber nun habe ich alles in einen BaseAdapter umgewandelt um den Timer weg zu bekommen und nun läuft die App besser als vorher und das Problem mit den durchstreichen hat sich auch er übrigt.

Ein Timer bekomme ich allerdings nicht weg, da der Timer alle 20 Sekunden die App anstößt die Daten mit der Online MySQL Datenbank abzugleichen. Oder habt ihr dafür auch eine elegantere Lösung?

Vielen Dank an alle die geholfen haben.

MfG
Thomas
 
Zurück
Oben Unten