Fehlerhafte ListView Anzeige beim Scrollen

  • 9 Antworten
  • Letztes Antwortdatum
H

Heppy1985

Neues Mitglied
0
Hallo
hab da mal ein Problem mit nem ListView,
ich fülle es mit Daten ohne Probleme sobalt die liste aber länger wird als die anzeige gros ist, werden die Daten nicht mehr ordnungsgemäß und ändern sich selbständig beim Scrollen.

Wie auf den Bildern zu sehen ändert sich der der erste Eintrag der beim Start nicht zu sehen ist ständig ab in den der als nächstes ins Bild kommen sollte.... und alle darauf folgenden Einträge enthalten werte von Einträgen vom Anfang der ListView.

app1.jpg app2.jpg app3.jpg
 
Code wäre gut...mit dem Adapter und so


Da wird bei dir alles einfach iregndwie durcheinander gewürfelt nciht nur der erste eintrag :)

Und eine nähere Beschriebung des Problems wäre auch gut:
Wird die Listview während der Laufzeit vergößert oder nur beim Star einmal gesetzt?
Passiert das beim Scrollen alleine und ändert sich immer weiter umso mehr man scrollt?

Da scheint aber ein Problem mit den Views vorzuliegen die fehlerhaft recycelt werden bzw du amchst da irgendwas das das recyclen nciht so glatt über die Bühne geht
 
Zuletzt bearbeitet:
Code:
package de.rudolf_heppner.dermanager.berichte;

import android.app.Activity;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;

import de.rudolf_heppner.dermanager.R;
import de.rudolf_heppner.dermanager.db_Helfer;
import de.rudolf_heppner.dermanager.kundenverwaltung.kv_kunden_auswaehlen;
import de.rudolf_heppner.dermanager.stundenlogger.StundenLogger;
import de.rudolf_heppner.dermanager.stundenlogger.ZeitAbfragen;
import de.rudolf_heppner.dermanager.stundenlogger.sl_bericht;

import static de.rudolf_heppner.dermanager.stundenlogger.Konstanten.SL_SPALTE_AZ_ANFANG;
import static de.rudolf_heppner.dermanager.stundenlogger.Konstanten.SL_SPALTE_AZ_ENDE;
import static de.rudolf_heppner.dermanager.stundenlogger.Konstanten.SL_SPALTE_AZ_UNTERSCHIED;
import static de.rudolf_heppner.dermanager.stundenlogger.Konstanten.SL_SPALTE_BERICHT;
import static de.rudolf_heppner.dermanager.stundenlogger.Konstanten.SL_SPALTE_KUNDE;

/**
* Created by Heppy on 16.07.2015.
*/
public class be_monat_stunden_lv_adapter extends BaseAdapter {
    public HashMap<Integer, Integer> list;
    public db_Helfer dbHelfer = null;

    Activity activity;
    TextView txtDatum;
    TextView txtStunden;

    String abfrageMonat;
    public be_monat_stunden_lv_adapter(Activity activity, HashMap<Integer, Integer> list, String abfrageMonat) {
        super();
        this.activity = activity;
        this.list = list;
        this.abfrageMonat = abfrageMonat;
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    public String getdb_ID(int position) {
        return db_Helfer.stunden_spalten_ids.get(position).toString();
    }

    @Override
    public View getView(final int position, View convertView, final ViewGroup parent) {
        View view = null;
        LayoutInflater inflater = activity.getLayoutInflater();

        if (convertView == null){
            convertView = inflater.inflate(R.layout.be_monat_stunden_liste, null);

            txtDatum = (TextView) convertView.findViewById(R.id.be_monats_stunden_liste_spalte_datum);
            txtStunden = (TextView) convertView.findViewById(R.id.be_monats_stunden_liste_spalte_stunden);

//            txtDatum.setOnClickListener(new View.OnClickListener() {
//                @Override
//                public void onClick(View v) {
//                    if (dbHelfer.stunden_spalten_ids.get(position).toString() != "-1") {
//                        Intent i = new Intent(activity, ZeitAbfragen.class);
//                        String id = getdb_ID(position);
//                        i.putExtra(StundenLogger.KEY, activity.getString(R.string.stundenlogger_update_az_anfang));
//                        i.putExtra(StundenLogger.KEY_ID, id);
//                        i.putExtra(activity.getString(R.string.stundenlocker_anderes_datum), StundenLogger.abfragedatum);
//                        activity.startActivityForResult(i, StundenLogger.REQUEST_ID);
//                    }
//                }
//            });
        }
        String aktuellerTag;
        if(position < 9) {
            aktuellerTag = "0" + (position+1);
        } else {
            aktuellerTag = "" + (position+1);
        }
        txtDatum.setText(aktuellerTag+"."+abfrageMonat);
        txtStunden.setText("Stunden: "+list.get(position+1));

        return convertView;
    }

}

also wenn ich die app starte dann wird alles normal angezeigt und sobald ich dan anfange die liste hoch zu ziehen wird in dem ersten Eintrag der neu im bild erscheint immer der nächste neue Eintrag angezeigt.
also wie in den Bildern zu sehen. im Feld 22.08.2015 steht auf einmal 23... 24.... 25.... 26.... usw bis zum letzten Eintrag dem 31... wenn ich wieder hoch scrolle dann ändert sich der Eintrag der ja normal fix auf 22.08.2015 stehen sollte auf 10... 09.... 08.... 07
und wenn ich schnell hoch und runter scrolle dann haut der einfach alles durcheinander.....
ich raff das einfach nit, da ich immer dachte wenn ich die werte einmal zuweise bleiben die halt so aber ka was der misst soll.
Wäre cool wenn du mir helfen könntest wenn du noch anderen Code haben willst ka aus dem db_helper.class so sag bescheid...

Danke

Ich gebe dem listview beim erstellen gleich alle 31 Daten also wird eigentlich nix aktualisiert wärend der Laufzeit
 
Hallo Heppy1985,

dein Fehler ist ein Feature von Android bei ListViews.
Android lässt nämlich nur ein paar Views der Liste im Speicher um Speicher zu sparen.

Ich würde dir empfehlen einen ViewHolder zu benutzen.
Hier ein wenig Code, der dir vielleicht hilft. Sonst müsstest du einfach bei Vogella nachschauen:
Using lists in Android (ListView) - Tutorial

Code:
public class MenueBaseAdapter extends BaseAdapter {

    ArrayList<MenueItem> menueItemArrayList = new ArrayList<MenueItem>();
    LayoutInflater inflater;
    Context context;

    public MenueBaseAdapter(Context context, ArrayList<MenueItem> items){
        this.menueItemArrayList = items;
        this.context = context;
        inflater = LayoutInflater.from(this.context);
    }


    public int getCount(){
        return menueItemArrayList.size();
    }

    public MenueItem getItem (int position){
        return menueItemArrayList.get(position);
    }

    public long getItemId (int position){
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ViewHolder holder; // create a ViewHolder reference
        //check to see if the reused view is null or not, if is not null then reuse it
        if (convertView == null){
            convertView = inflater.inflate(R.layout.menue_mylist_layout,null);
            holder = new ViewHolder();
            holder.aaa = (ImageView) convertView.findViewById(R.id.Item);
            holder.bbb = (TextView) convertView.findViewById(R.id.Titel);
            // the setTag is used to store the data within this view
            convertView.setTag(holder);
        }
        else{
            // the getTag returns the viewHolder object set as a tag to the view
            holder = (ViewHolder) convertView.getTag();
        }

      

     
                holder.aaa.setImageResource(cccc.getImage());
            }
            if(holder.bbb != null){
                holder.bbb.setText(ddd.getText());
            }
        }


        return convertView;
    }

    static class ViewHolder{
        ImageView aaa;
        TextView bbb;
    }

}
 
  • Danke
Reaktionen: Heppy1985 und missspelled
Nice, hilfreiche Info bzgl. des Speichers (ich hatte mich immer gewundert, warum meine Listen über den ViewHolder immer fehlerfreier laufen^^)
 
Danke klappt soweit gut nur leider hat sich nun ein neues Problem herausgestellt in diesem Zusammenhang:
ich frage die einzelnen zeilen und spalten normal per onClick ab und reagiere auf die dann übergebene Position, jedoch fängt die Position jetzt wieder bei 0 an bei den Elementen die ins Bild scrollen anstelle einfach weiter zu zählen... kann man das umgehen oder muss ich damit leben???
 
Dann scheinst du was falsch zu machen, zeig mal deinen onClick Code.
Die Position bezieht sich eigentlich auf die Position im Adapter, nicht der gerade aktuell sichtbaren Views. Außer du hast da irgendwas umständlich drumrum gebaut.
 
Ich poste jetzt etwas mehr als nur den onClick teil dort nur auf zwei variablen zugegriffen wird von denen die eine ->aktuellerTag<- nicht mehr stimmt bei den list view Einträgen die neu ins Bild gescrollt werden. Wie ihr sehen könnt besteht diese Variable aus einem String und der Position, welche aber wie gesagt bei listen Elementen Außerhalb des sichtbaren Bereiches beim erzeugen liegen wieder neu anfängt bzw die Position der Elemente bekommt die dann raus gescrollt werden.

Code:
final String aktuellerTag;
        if(position < 9) {
            aktuellerTag = "0" + (position+1);
        } else {
            aktuellerTag = "" + (position+1);
        }

        if (convertView == null){
            convertView = inflater.inflate(R.layout.be_monat_stunden_liste, null);
            holder = new ViewHolder();
            holder.datum = (TextView) convertView.findViewById(R.id.be_monats_stunden_liste_spalte_datum);
            holder.stunden = (TextView) convertView.findViewById(R.id.be_monats_stunden_liste_spalte_stunden);

            holder.datum.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    StundenLogger.restart(activity, aktuellerTag+"."+abfrageMonat);
                }
            });

            // the setTag is used to store the data within zhis view
            convertView.setTag(holder);
        }
else {
// the getTag retuns the viewHolder object set as a tag to the viewholder = (ViewHolder) convertView.getTag();
}
if(holder.stunden != null) {
holder.stunden.setText("Stunden: " + list.get(position+1));
}
if (holder.datum != null) {
holder.datum.setText(aktuellerTag+"."+abfrageMonat);
}

return convertView;
 
Zuletzt bearbeitet:
Hi,

ich habe gerade nochmal bei mir im Code nachgeschaut.
Wir machen ein OnClickListener auf die ConvertView.
Hast du auch den Else-Fall, if converView != null?
 
Hi Kardroid,
ja das mit dem ConvertView kann man machen aber ich habe die Anforderung das ein unterschiedliches Ereignis beim klicken in der gleichen zeile aber anderer spalte ausgelöst wird. dazu wurde mir halt dieser weg ans herzgelegt.
Ja gibt noch ne else Anweisung ich hab den rest des codes oben im Code angefügt

Okay Problem gelöst....
nach dem setText habe ich dem ViewHolder noch die Position übergeben.
und diesen dann im OnClick abgefragt.
 
Zurück
Oben Unten