ListActivity - nur den Hintergrund vom ausgewählten Eintrag ändern

L

Laersieh

Neues Mitglied
0
Hallo liebe Community ... *schleim*

bin neu hier wie man sieht und wollte euch sofort mal mit meinem Problem belästigen da ich nicht wirklich eine Antwort durchs googeln finde.

Ich habe eine Liste aus folgendem Tutorial erstellt: Android Series: Custom ListView items and adapters | Software Passion

Funktioniert ganz gut soweit, allerdings habe ich 'versucht', in der Methode "getView(...)" mit 'v.setBackgroundColor(selectedLineBGColor);' den die Hintergrundfarbe des von mir angeklickten Eintrages auszuwählen (in meinem Fall 'weiß'). Soweit so gut, dass Problem besteht jetzt allerdings darin, dass nach jedem 6. Eintrag der Darauffolgende wieder 'weiß' gefärbt wird und nach den Nächsten 6 Einträgen schon wieder ..

Da ich die ListActivity noch nicht ganz durch habe, was das Verständnis angeht tue ich mir hier relativ schwer.
Ich vermute, dass nur ein Fragment der eigentlichen Einträge durch die View dargestellt wird (etwa Displayhöhe) und in diesem Listenfragment jeweils von Neuem an, also von '0' fortan gezählt wird.

Hat da jemand vielleicht auch eine elegantere oder einfacherere Lösung für mich, wie ich nur 'einen' Eintrag färben könnte ?

Danke euch schon jetzt im Voraus ! :smile:
 
Setzt du die Hintergrundfarbe denn auch zurück wenn irgendwo anders hingeklickt wird oder weiter durchgescrollt wird? Der View wird ja recycled und wenn du die Hintergrundfarbe nicht wieder zurück änderst bleibt es dabei.
 
Ja, mit folgender selbstgeschriebenen einfachen Methode:

// Reset aller Zeilen
public static void reset(AdapterView<?> parent) {
try {
// Reset
for (int i = 0; i < parent.getCount(); i++) {
View v = parent.getChildAt(i);
v.setBackgroundColor(Color.BLACK);

TextView tx1 = (TextView) v.findViewById(R.id.toptext);
TextView tx2 = (TextView) v.findViewById(R.id.bottomtext);

tx1.setTextColor(Color.GRAY);
tx2.setTextColor(Color.GRAY);
}

// Werte löschen
delValues();

} catch (Exception e) {
e.printStackTrace();
}
}


---
Das Problem tritt ja schon auf, wenn ich die ListView aufrufe/öffne und den Ersten Klick vollführe. In dem Moment wird im Sichtbereich der Liste natürlich nur der Ausgewählte Eintrag geändert (Hintergrund und Schriftfarbe werden angepasst). Scrolle ich nun etwas weiter herunter, ist der (bei mir) 7. Eintrag wieder ausgewählt und 6 Einträge weiter dasselbe ...

Hab's gedebuged, aber leider komme ich auf keinen richtigen Nenner. :crying:

Darum geht meine Vermutung in die Richtung, dass Android die List jeweils für den Sichrbereich von '0' an durchnummeriert.
 
Rufst du die reset Methode auf sobald gescrollt wird?
 
Nein, beim OnItemClick(...) des OnItemClickListeners.

Wie kann ich das beim Scrollen aufrufen ? Ein Beispiel wie ich das damit lösen könnte ?
 
Am besten gar nicht ;)

Aber du solltest in getView(...) überprüfen ob das aktuelle Item markiert sein soll oder nicht und dann entsprechend die Hintergrundfarbe setzen.
 
Habe ich folgendermaßen versucht:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.groupsettings_singlerow, null);
}
Order o = pItems.get(position);

if (o != null) {
TextView tt = (TextView) v.findViewById(R.id.toptext);
TextView bt = (TextView) v.findViewById(R.id.bottomtext);
if (position == currPosition) {

// !!! TEST ---
String vStr1, vStr2;
Tools tools = new Tools();

vStr1 = tt.getText().toString().substring(tools.SearchStringFrom(0, tt.getText().toString(), ":")+2, // "+2" wegen Leerzeichenausgleich !
tt.getText().length());
vStr2 = bt.getText().toString().substring(tools.SearchStringFrom(0, bt.getText().toString(), ":")+2,
bt.getText().length());
// ------------

// HIER (!) WIRD ÜBERPRÜFT, OB DER EINTRAG GESETZT WERDEN
// SOLL ...
if (value1.equals(vStr1)) { // <- !!! TEST
// Textfarbe in ändern
tt.setTextColor(selectedTextColor);
bt.setTextColor(selectedTextColor);

// Hintergrundfarbe der Zeile ändern
v.setBackgroundColor(selectedLineBGColor);
}
}

if (tt != null) {
tt.setText(txt.nameEntry + " " + o.getOrderName()); }
if (bt != null) {
bt.setText(txt.membersCountEntry + " " + o.getOrderCount());
}
}
return v;
}


---
Die (Test-)Einträge verlaufen mit Bezeichnungen von "Gruppe A" bis "Gruppe L". Nach dem ersten Anklicken in der Liste (z.B.) auf den Eintrag 'Gruppe A' (indem Fall index = 0), erhalte ich für (String) "value1" entsprechend 'Gruppe A', jedoch für den Vergleich mir (String) "vStr1" leider schon 'Gruppe G'. (?)
 
Woher kommt denn "value1"?
 
steht doch drüber: das soll der vergleich sein, der bestimmt, welche farbe der eintrag bekommt. das musst du dann schon selbst bestimmen, was dort stehen soll :D
 
Um den Hintergrund eines angeklickten Items zu ändern gibt es Selector. Dort definierst du dir für die zwei Zustände - gedrückt und ungedrückt zwei verschiedene Hinergrundbilder und wählst als Hintergrund für das ItemLayout den Selector.

Die Android Dokumentation sollte dazu relativ ergiebig sein.
 
gibt es bei einem listview element einen checked state?? ich glaube das funktioniert so nicht
 
nicht checked, aber pressed
 
Kommt es nur mir so vor oder ist der Check viel zu riesig? Ich hätte mir ne List<int> gemacht und alle positionen die markiert werden sollen darin gespeichert und hätte dann einfach List#contains(int) benutzt um zu checken welche Hintergrundfarbe ich jetzt setzen soll.
Oder bin ich gerade total auf dem Holzweg?
 
cypressious schrieb:
nicht checked, aber pressed


ja klar, aber pressed ist nicht das was er will. er möchte einen eintrag für den user sichtbar selektieren ( wenn ich das richtig verstanden habe )

da kommt er mit pressed nicht weit
 
'value1' ~und~ 'value2' sind zwei Klassenvariablen, die jeweils einen String-Eintrag speichern, der ausgewählt wurde. Innerhalb eines Listeneintrages sind zwei Werte angegeben.

In meinem Fall speichere ich dort einen Gruppennamen und die Mitgliederanzahl einer Gruppe.

'value1' wird an der Stelle (testweise) nur dazu verwendet, um zu überprüfen, ob der zu färbende Eintrag aus der Liste, auch wirklich der ausgewählte ist.

---
Danke für den Tipp mit dem 'Selector', werd gleich mal etwas googeln ... :smile:
 
Laersieh schrieb:
'value1' ~und~ 'value2' sind zwei Klassenvariablen, die jeweils einen String-Eintrag speichern, der ausgewählt wurde. Innerhalb eines Listeneintrages sind zwei Werte angegeben.

In meinem Fall speichere ich dort einen Gruppennamen und die Mitgliederanzahl einer Gruppe.

'value1' wird an der Stelle (testweise) nur dazu verwendet, um zu überprüfen, ob der zu färbende Eintrag aus der Liste, auch wirklich der ausgewählte ist.

---
Aber das kann doch nicht funktionieren wenn du den Text des Views erst setzt nachdem du den Text des Views überprüft hast. Dann steht da doch noch der alte Kram drin.
 
Ja, hast Recht. Ich sehe gerade, dass ich die Abfrage an eine total verkehrte Stelle geklatscht habe. Muß ein Flüchtigkeitsfehler gewesen sein ...

Im getView(...) soll eingentlich beim füllen der Liste der bereits ausgewählte (und gecachte) Eintrag beim Zurückkehren in die ListView markiert werden, um dem User den bereits ausgewählten und aktiven Eintrag anzuzeigen.

So wäre es also (wieder) richtig:
-------------------------------
.
..
...
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.groupsettings_singlerow, null);
}
Order o = pItems.get(position);

if (o != null) {
TextView tt = (TextView) v.findViewById(R.id.toptext);
TextView bt = (TextView) v.findViewById(R.id.bottomtext);

if (position == currPosition) {

// Textfarbe in ändern
tt.setTextColor(selectedTextColor);
bt.setTextColor(selectedTextColor);

// Hintergrundfarbe der Zeile ändern
v.setBackgroundColor(selectedLineBGColor);
}

if (tt != null) {
tt.setText(txt.nameEntry + " " + o.getOrderName()); }
if (bt != null) {
bt.setText(txt.membersCountEntry + " " + o.getOrderCount());
}
}
return v;
}
...
..
.


Werde die Vergleichsprüfung sofort mal kurz in den OnClickListener setzen und es nochmal probieren ...

EDIT: Nein ... leider keine Änderung ... (irgendwie verständlich ..) ;)
 
Zuletzt bearbeitet:
Du änderst die Hintergrundfarbe ja auch immer noch nicht zurück...

Die Views werden wiederverwendet. Also du setzt bei dem ersten Eintrag die Hintergrundfarbe auf #FFF, scrollst durch die Liste, der View mit der Hintergrundfarbe #FFF wird wiederverwendet damit kein neuer erstellt werden muss. Du überprüfst ob du die Hintergrundfarbe auf #FFF setzen musst, aber es ist nicht der richtige Eintrag und lässt es wie es ist. Folge: Hintergrundfarbe #FFF
 
Das habe ich schon verstanden. Deshalb habe ich im OnClickListener auch vor jeder Auswahl ein Reset.
Damit es so funktioniert wie du es auch meinst, müsste der Reset bei jeder Aktualisierung der View geschehen. In dem Fall wohl über das 'OnScroll' Ereignis.

Habe der 'ListActivity' die 'ListView.OnScrollListener' implementiert und die beiden Methoden "OnScroll(...)" und "OnStateChanged(...)" hinzugefügt.

Leider scheint sich dennoch nichts geändert zu haben ... ich kriege leider auch keine Exception an der Stelle trotz abgefangener Exception über '.printStackTrace()' nichts aus ...

Bin echt langsam am Verzweifeln.
Ist wirklich echt Umständlich mit der ganzen DalvikVM/Java Geschichte .. ;-)


Nun, ich muß dennoch hier weiterkommen.
Hat jemand von euch ein Brauchbares Beispiel, das ~vielleicht~ so ähnlich funktioniert ?
 
Laersieh schrieb:
Damit es so funktioniert wie du es auch meinst, müsste der Reset bei jeder Aktualisierung der View geschehen.

Genau! Oder bei jedem Zeichnen den Hintergrund setzen...
Code:
if(isSelected(position) {
    view.setBackground(R.color.selected);
}else{
    view.setBackground(R.color.normal);
}
 
  • Danke
Reaktionen: Laersieh

Ähnliche Themen

S
Antworten
9
Aufrufe
1.151
swa00
swa00
D
Antworten
14
Aufrufe
1.648
chrs267
chrs267
C
  • Chicken Wing
Antworten
4
Aufrufe
822
Chicken Wing
C
Zurück
Oben Unten