Android ListView, Werte aktualisieren ohne die Liste komplett neu zu laden

insidERR

Mitglied
Hallo zusammen,
ich habe eine (Custom) ListView mit mehreren TextViews und der Möglichkeit die Zeile farblich zu markieren. Habe es über ein über die ganze Zeile gelegtes TextView mit "alpha =0.5" gelöst.

Die ListView wird über einen Adapter gefüttert und ich komme beim Klick auf die einzelnen Werte. Klappt alles wunderbar.
Nun habe ich das Problem, dass wenn die ListView so viele Zeilen hat, dass es zu große fürs Display wird und Scrollbalken auftauchen. Was kein Problem ist.

Wenn ich aber die einzelnen Werte in den Zeilen aktualisieren will, ändere ich im besagten Adapter die Werte mit xZelle_1.set(Pos,"neuer Wert");
Die Werte werden dann im Speicher übernommen. Damit die ListView das übernimmt, setze ich den Adapter neu. Dadurch werden zwar die ganzen Werte aktualisiert, die Liste springt aber auf den Anfang zurück. Daran scheitere ich. Ich hätte es gerne so, dass wenn man z.B. runter scrollt und dort ein Wert ändert, dass die Zahl live geändert wird, ohne dass die Liste gelöscht und direkt neu aufgebaut wird.

Im Netz hatte ich schon gefunden, dass man bei der ListView ein ".notify();" auslöst.
Wenn ich das tue, schmiert die App mit der Fehlermeldung "object not locked by thread before notify()" ab :-(

Frage: hat jemmand ne Idee, wie man die Liste aktualisiert, ohne die Liste neu zu laden?
Danke :)


Hier mein Code:
Java:
public class MainActivity extends AppCompatActivity {
    Button cmdListe;
    ArrayList<String> xZelle_1 = new ArrayList<>();
    ArrayList<String> xZelle_2 = new ArrayList<>();
    ArrayList<String> xZelle_3 = new ArrayList<>();
    ArrayList<String> xZelle_4 = new ArrayList<>();
    ArrayList<String> xZelle_5 = new ArrayList<>();
    ArrayList<Integer> xFarbe = new ArrayList<Integer>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        cmdListe=findViewById(R.id.buttonListe);

        ListView FarbListe = findViewById(R.id.lstDetailListe);
        myListViewAdapter AdapterListe = new myListViewAdapter(FarbListe.getContext(),xZelle_1,xZelle_2,xZelle_3,xZelle_4,xZelle_5,xFarbe);

        AddTextToList("1.12345","11","21","01.02.03.04.05","Welle XYZ 1",getResources().getColor(R.color.Schriftfarbe_gruen));
        AddTextToList("2.12345","12","12","02.02.03.04.05","Welle XYZ 2",getResources().getColor(R.color.Schriftfarbe_markiert));
        AddTextToList("3.12345","1","2","01.02.03.04.05","Welle XYZ 3",getResources().getColor(R.color.Schriftfarbe_warnung));
        AddTextToList("3.12345","1","2","01.02.03.04.05","Welle XYZ 3",getResources().getColor(R.color.Schriftfarbe_warnung));


        //Klick auf DetailListe
        FarbListe.setOnItemClickListener((parent, view, position, id) -> {
            String tmpZeile1; tmpZeile1=xZelle_1.get(position);
            System.out.println("tmpZelle_1: " + tmpZeile1);
            ChangeTextAtList(position,xZelle_1.get(position),xZelle_2.get(position),xZelle_3.get(position),xZelle_4.get(position),xZelle_5.get(position),getResources().getColor(R.color.Schriftfarbe_markiert));
        });


    }

//Text in die ListView eintragen
    void AddTextToList(String Zelle_1, String Zelle_2, String Zelle_3, String Zelle_4, String Zelle_5, Integer ZellenFarbe){
        //Farbwert als getResources().getColor(R.color.Schriftfarbe_gruen)   eingeben
        xZelle_1.add(Zelle_1); xZelle_2.add(Zelle_2); xZelle_3.add(Zelle_3); xZelle_4.add(Zelle_4); xZelle_5.add(Zelle_5); xFarbe.add(ZellenFarbe);
        ListView FarbListe = findViewById(R.id.lstDetailListe);
        myListViewAdapter AdapterListe = new myListViewAdapter(FarbListe.getContext(),xZelle_1,xZelle_2,xZelle_3,xZelle_4,xZelle_5,xFarbe);
        FarbListe.setAdapter(AdapterListe);
    }

//Text in der ListView ändern
    void ChangeTextAtList(Integer Pos, String Zelle_1, String Zelle_2, String Zelle_3, String Zelle_4, String Zelle_5, Integer ZellenFarbe){
        //Farbwert als getResources().getColor(R.color.Schriftfarbe_gruen)   eingeben
        xZelle_1.set(Pos,Zelle_1); xZelle_2.set(Pos,Zelle_2);xZelle_3.set(Pos,Zelle_3);xZelle_4.set(Pos,Zelle_4);xZelle_5.set(Pos,Zelle_5); xFarbe.set(Pos,ZellenFarbe);
        ListView FarbListe = findViewById(R.id.lstDetailListe);
        FarbListe.notify();   // <--- HIER PASSIERT DER FEHLER

      // das hier funktioniert, lässt die Liste aber auf den Anfang springen
       myListViewAdapter AdapterListe = new myListViewAdapter(FarbListe.getContext(),xZelle_1,xZelle_2,xZelle_3,xZelle_4,xZelle_5,xFarbe);
       FarbListe.setAdapter(AdapterListe); //DAS WILL ICH VERMEIDEN
    }

    class myListViewAdapter extends ArrayAdapter<String> {
        Context context; String[] rZelle_1; String[] rZelle_2; String[] rZelle_3; String[] rZelle_4; String[] rZelle_5; Integer[] rColor;

        myListViewAdapter (Context c, ArrayList<String> Zelle_1, ArrayList<String> Zelle_2, ArrayList<String> Zelle_3, ArrayList<String> Zelle_4, ArrayList<String> Zelle_5, ArrayList<Integer> FarbWert) {
            super(c, R.layout.farbliste, R.id.txtZelle_1, Zelle_2);
            this.context = c;
            this.rZelle_1 = Zelle_1.toArray(new String[0]);
            this.rZelle_2 = Zelle_2.toArray(new String[0]);
            this.rZelle_3 = Zelle_3.toArray(new String[0]);
            this.rZelle_4 = Zelle_4.toArray(new String[0]);
            this.rZelle_5 = Zelle_5.toArray(new String[0]);
            this.rColor   = FarbWert.toArray(new Integer[0]);
        }


        @Override
        public View getView(int position,  View convertView,  ViewGroup parent) {
            LayoutInflater layoutInflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View row = layoutInflater.inflate(R.layout.farbliste, parent, false);

            TextView Zelle_1 = row.findViewById(R.id.txtZelle_1);
            TextView Zelle_2 = row.findViewById(R.id.txtZelle_2);
            TextView Zelle_3 = row.findViewById(R.id.txtZelle_3);
            TextView Zelle_4 = row.findViewById(R.id.txtZelle_4);
            TextView Zelle_5 = row.findViewById(R.id.txtZelle_5);
            TextView FarbZeile = row.findViewById(R.id.Hintergrundfarbe);

            Zelle_1.setText(rZelle_1[position]);
            Zelle_2.setText(rZelle_2[position]);
            Zelle_3.setText(rZelle_3[position]);
            Zelle_4.setText(rZelle_4[position]);
            Zelle_5.setText(rZelle_5[position]);
            FarbZeile.setBackgroundColor(rColor[position]);
            return row;
        }
    }
 
Zuletzt bearbeitet:

KonradN

Super-Moderator
Mitarbeiter
Also generell sollte es nicht notwendig sein, den Adapter neu zu setzen. Aber Dein Cod eist auch extrem unleserlich - ich würde Dir raten, dich an die üblichen Styleguides zu halten und Variablen z.B,. mit einem kleinen Buchstaben anfangen zu lassen. Ebenso Methoden. Klassen dafür mit einem großen Buchstaben starten.Dann nicht mehrere Dinge in eine Zeile packen.

Und dann ist myListViewAdapter eine innere Klasse? In der hast Du arrays rZelle_? Und Du hast die Werte aber selbst in der Activity mit xZelle_?

Das ist irgendwie etwas irritierend.

Was man machen sollte:
a) Statt ganz vieles Listen / Array / Was auch immer: Eine Model-Klasse, in der die Werte drin sind. Dann eine List mit den Elementen dieser Model Klasse.
b) Die Adapter Klasse hat dann die Liste. Da gehört diese dann rein.

Dann reicht es übrigens auch, da in der Liste etwas zu ändern.

Das Problem ist bei Dir ja, dass Du da nur in der Activity irgendwas anpasst. Das da etwas angepasst werden soll an der Anzeige bekomt der Adapter ja nicht mit. Aber da mag ich mich auf die Schnelle auch irren - denn bei den Bezeichnern und so möchte man nicht wirklich Zeit mit dem Code zubringen (sorry).

Ich habe durch Zufall übrigens auf SO etwas gefunden, das zeigt, wie sowas aussehen könnte:
Dann hast Du ein Beispiel.

Und das Thema
und der Möglichkeit die Zeile farblich zu markieren. Habe es über ein über die ganze Zeile gelegtes TextView mit "alpha =0.5" gelöst.
habe ich jetzt nicht weiter behandelt. Das ist aber so auch überkompliziert und recht dubios.
 

insidERR

Mitglied
Hey Konrad,
vielen Dank für deine Antwort.
Sorry, für den (für Fachleute) unübersichtlichen und überladenen Code. Ist meine erste AndroidApp und Arbeit mit Java.
Komme aus der VB/A Welt und muss mich noch an die Groß/kleinschreibung uns sonst was bei Java gewöhnen bzw umstellen.
Konstruktive Kritik ist immer willkommen, vorallem wenn sie dann zum Ziel führt.
Dein Link ist genau das, wonach ich gesucht hatte. Musste den Code etwas anpassen, da ich mehr als nur ein Wert habe, mit dem ich arbeite.

Das mit "Zeile farblich zu markieren" ist ein Trick, weil ich es einfach nicht besser weis und in einem Forum gesehen habe, weil dort jemand ein ähnliches Problem hatte.
 

KonradN

Super-Moderator
Mitarbeiter
Bezüglich der angesprochenen Coding Guidelines: Da habe ich mal folgenden Link gefunden, der evtl. interessant ist:

Das macht das Lesen etwas einfacher.

Am Anfang ist es durchaus normal, dass man gewisse Dinge oft mal etwas über kompliziert macht - und da hilft es, wenn dann wenigstens paar Rahmenbedingungen stimmen.

Konntest Du denn den Code mit den Hinweisen soweit umstellen? Oder sollte man da ggf. mal direkt auf den Code schauen? Wenn das Projekt noch nicht so groß ist, kann kannst Du ggf, mal das Projekt bereitstellen. Dann könnte man sowas ggf. mal schnell überarbeiten und mit Kommentaren zurück geben.
 

insidERR

Mitglied
Hey Konrad,
danke für den Link. Werde ich mir mal in ner ruhigen Minuten genauer ansehen.
Bin froh, dass das Projekt überhaupt läuft. Ist noch lange nicht fertig. Appetit kommt ja bekanntlich beim Essen und die Esser (Benutzer) haben mit jeder neuen Funktion neue Ideen.
Es ist eine App für einen Handscanner (Bar/QRcode) der im Lager eingesetzt wird. Ich hatte schon mal ne Frage dazu gehabt.
Bin jetzt auf jeden Fall weiter gekommen. Vielen Dank.
Die ListView wird mit mehreren Werten gefüttert und ich kann darauf zugreifen und die Werte beliebig ändern. Beim Anklicken einer beliebigen Zeile wird sie farbig markiert und die zuletzt angeklickte Zeile bekommt ihre ursprüngliche Farbe wieder.
Konntest Du denn den Code mit den Hinweisen soweit umstellen?
Ja. Wenn du drauf gucken willst, hier ist meine Version (Spielwiese). Tut was sie soll.
Java:
package com.example.farblistview;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    Button cmdListe;
    private ItemAdapter itemListAdapter;
    private final List<ListenEintrag> itemList = new ArrayList<>();
    int letztelistenauswahl; int letztelistenfarbe;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        cmdListe = findViewById(R.id.buttonListe);
        ListView listView = findViewById(R.id.lstDetailListe);

        itemListAdapter = new ItemAdapter(itemList, this);
        listView.setAdapter(itemListAdapter);
        //listView.setFastScrollEnabled(true);

        cmdListe.setOnClickListener(v->
        {
            ////////////////////////////////////////////////
            // add some items
            itemList.add(new ListenEintrag("1.23456", "1", "1", "01.01.01.01.01", "Welle XYZ", getResources().getColor(R.color.Schriftfarbe_gruen)));
            itemList.add(new ListenEintrag("2.23456", "1", "1", "01.01.01.01.01", "Welle XYZ", getResources().getColor(R.color.Schriftfarbe_gruen)));
            itemList.add(new ListenEintrag("3.23456", "1", "1", "01.01.01.01.01", "Welle XYZ", getResources().getColor(R.color.Schriftfarbe_gruen)));
            itemList.add(new ListenEintrag("2.23456", "22", "21", "02.02.01.01.01", "Spirale XYZ", getResources().getColor(R.color.Schriftfarbe_warnung)));
            itemList.add(new ListenEintrag("2.23456", "22", "21", "02.02.01.01.01", "Spirale XYZ", getResources().getColor(R.color.Schriftfarbe_warnung)));
            itemList.add(new ListenEintrag("2.23456", "22", "21", "02.02.01.01.01", "Spirale XYZ", getResources().getColor(R.color.Schriftfarbe_warnung)));
            itemList.add(new ListenEintrag("2.23456", "22", "21", "02.02.01.01.01", "Spirale XYZ", getResources().getColor(R.color.Schriftfarbe_warnung)));

            //add new items and changes to adapter
            itemListAdapter.notifyDataSetChanged();

            ////////////////////////////////////////////////
        });

        listView.setOnItemClickListener((adapterView, view, position, id) -> {
            if(letztelistenfarbe !=0){
                System.out.println("Position: " + position +
                                   " ; Farbe: " + itemListAdapter.getItem(position).getFarbe());
                itemListAdapter.getItem(letztelistenauswahl).setFarbe(letztelistenfarbe);}

            letztelistenauswahl=position; letztelistenfarbe=itemListAdapter.getItem(position).getFarbe();

            itemListAdapter.getItem(position).setMaterial("8.00001");
            itemListAdapter.getItem(position).setLagerort("00.00.00.00.00");
            itemListAdapter.getItem(position).setFarbe(getResources().getColor(R.color.Schriftfarbe_markiert));

            itemListAdapter.notifyDataSetChanged();
        });

    }


    public static class ItemAdapter extends ArrayAdapter<ListenEintrag> {
    //Quelle: https://stackoverflow.com/questions/30711517/how-to-change-the-contents-of-listview-on-item-click/30711959#30711959

        private final List<ListenEintrag> itemList;
        Context context;

        @Override
        public void add(ListenEintrag object) {
            itemList.add(object);
            super.add(object);
        }

        public ItemAdapter(List<ListenEintrag> rList, Context context) {
            super(context, R.layout.farbliste);
            this.context = context;
            this.itemList = rList;
        }

        private static class ViewHolder {
            TextView txtMaterial;
            TextView txtZuBuchen;
            TextView txtGebucht;
            TextView txtLagerort;
            TextView txtBeschreibung;
            TextView txtFarbe;
        }

        public int getCount() {
            return this.itemList.size();
        }

        public ListenEintrag getItem(int index) {
            return this.itemList.get(index);
        }

        public View getView(int position, View convertView, ViewGroup parent) {

            ViewHolder holder = new ViewHolder();

            if (convertView == null) {
                LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(R.layout.farbliste, parent, false);

                holder.txtMaterial = convertView.findViewById(R.id.txtZelle_1);
                holder.txtZuBuchen = convertView.findViewById(R.id.txtZelle_2);
                holder.txtGebucht = convertView.findViewById(R.id.txtZelle_3);
                holder.txtLagerort = convertView.findViewById(R.id.txtZelle_4);
                holder.txtBeschreibung = convertView.findViewById(R.id.txtZelle_5);
                holder.txtFarbe = convertView.findViewById(R.id.Hintergrundfarbe);

                convertView.setTag(holder);
            } else
                holder = (ViewHolder) convertView.getTag();

            ListenEintrag ListenEintrag = getItem(position);

            holder.txtMaterial.setText(ListenEintrag.getMaterial());
            holder.txtZuBuchen.setText(ListenEintrag.getZuBuchen());
            holder.txtGebucht.setText(ListenEintrag.getGebucht());
            holder.txtLagerort.setText(ListenEintrag.getLagerort());
            holder.txtBeschreibung.setText(ListenEintrag.getBeschreibung());
            holder.txtFarbe.setBackgroundColor(ListenEintrag.getFarbe());
            return convertView;
        }

    }

    public static class ListenEintrag {
        private String material_nr;
        private String zu_buchen;
        private String gebucht;
        private String lagerort;
        private String beschreibung;
        private int farbe;

         public ListenEintrag(String material_nr, String zu_buchen, String gebucht, String lagerort,String beschreibung, int farbe) {
            this.material_nr = material_nr;
            this.zu_buchen=zu_buchen;
            this.gebucht=gebucht;
            this.lagerort=lagerort;
            this.beschreibung=beschreibung;
            this.farbe=farbe;
        }

        public String getMaterial() {
            return material_nr;
        }

        public String getZuBuchen() {
            return zu_buchen;
        }

        public String getGebucht() {
            return gebucht;
        }

        public String getLagerort() {
            return lagerort;
        }

        public String getBeschreibung() {
            return beschreibung;
        }

        public int getFarbe() {
            return farbe;
        }

        public void setMaterial(String material_nr) {
            this.material_nr = material_nr;
        }

        public void setZuBuchen(String zu_buchen) {
            this.zu_buchen = zu_buchen;
        }

        public void setGebucht(String gebucht) {
            this.gebucht = gebucht;
        }

        public void setLagerort(String lagerort) {
            this.lagerort = lagerort;
        }
        public void setBeschreibung(String beschreibung) {
            this.beschreibung = beschreibung;
        }

        public void setFarbe(int farbe) {
            this.farbe = farbe;
        }
    }
}
 

KonradN

Super-Moderator
Mitarbeiter
Ich habe mir den Code nicht im Detail angesehen, aber das sieht auf den ersten Blick schon sehr viel besser aus! Danke für die schnelle Adaption der Vorschläge!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J ListView Item individuell einfärben Android & Cross-Platform Mobile Apps 17
W ListView OnItemClicklistener setzen mit Ausgabe Android & Cross-Platform Mobile Apps 35
K Null-Pointer-Exception in ListView - wird über Datenbank gefüllt Android & Cross-Platform Mobile Apps 1
I Android ListView (Custom) soll auf Hardwaretasten nicht reagieren. Android & Cross-Platform Mobile Apps 10
W ListView und Arrays... Android & Cross-Platform Mobile Apps 68
W Android Wieso kann ich keine ListView mehr zum Layout hinzufügen? Android & Cross-Platform Mobile Apps 1
W Android Kann keine ListView mehr in der MainActivtiy anzeigen, obwohl noch sehr viel Platz frei ist Android & Cross-Platform Mobile Apps 1
L ListView aktuallisiert sich nicht Android & Cross-Platform Mobile Apps 15
N Probleme mit custom dynamic ListView Android & Cross-Platform Mobile Apps 15
L Android ListView kollabiert in Scrollview Android & Cross-Platform Mobile Apps 9
A ImageButton in ListView Item bei klick ändern Android & Cross-Platform Mobile Apps 3
J Android Suche in einer ListView Android & Cross-Platform Mobile Apps 3
H Android ArrayList <-> ArrayAdapter <-> ListView Android & Cross-Platform Mobile Apps 10
L Android ListView swipe zum löschen Android & Cross-Platform Mobile Apps 1
B Android ListView set custom check Image and delete Android & Cross-Platform Mobile Apps 0
M Android ListView wird nicht dargestellt Android & Cross-Platform Mobile Apps 2
Maresuke Android Android ListView Textfarbe und Texthintergrund ändern? Android & Cross-Platform Mobile Apps 5
A Android Problem mit ListView und OnItemClickListener.. Android & Cross-Platform Mobile Apps 10
S Listview Einträge aus "xml" Datei Android & Cross-Platform Mobile Apps 1
S Android Studio MySql Daten in Listview mit sub Item Android & Cross-Platform Mobile Apps 11
S Textdatei in ListView einlesen Tutorial gesucht!? Android & Cross-Platform Mobile Apps 3
kaoZ Tutorial .xml Layouting für z.B ListView elemente Android & Cross-Platform Mobile Apps 7
M Android ListView und Checkbox Android & Cross-Platform Mobile Apps 6
L TableRows in ListView darstellen Android & Cross-Platform Mobile Apps 2
M ListView mit ListAdapter füllen Android & Cross-Platform Mobile Apps 5
U Android ListView Frage Android & Cross-Platform Mobile Apps 6
L Android SearchBox für Custom Listview Android & Cross-Platform Mobile Apps 5
H Android ListView Images aus dem Internet via Thread Android & Cross-Platform Mobile Apps 3
T Android: ListView-Adapter: Adapter wird ständig aufgerufen Android & Cross-Platform Mobile Apps 2
H Android SAX|ListView NullPointerException Android & Cross-Platform Mobile Apps 2
A Probleme mit ListView / ArrayAdapter Android & Cross-Platform Mobile Apps 3
S Android ListFragment & ArrayAdapter - Button-Werte werden vergessen Android & Cross-Platform Mobile Apps 0
T x und y Werte richtig festlegen Android & Cross-Platform Mobile Apps 4
G Java ME Attribut(werte) von MIDlet übergeben Android & Cross-Platform Mobile Apps 6
X Wie kriege ich die RGB Werte von Bildern? ->getRGB()? Android & Cross-Platform Mobile Apps 6
E Android Zeichenview alle 3 Sekunden aktualisieren Android & Cross-Platform Mobile Apps 5
G Wie kann ich nachhelfen die R.java zu aktualisieren? Android & Cross-Platform Mobile Apps 3
P Android Aktualisieren des Listviews Android & Cross-Platform Mobile Apps 2
S Buttontext aktualisieren Android & Cross-Platform Mobile Apps 6

Ähnliche Java Themen

Neue Themen


Oben