1. Nimm jetzt an unserem Uhans - 3. ADVENT - Gewinnspiel teil - Alle Informationen findest Du hier!

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

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von Laersieh, 18.07.2011.

  1. Laersieh, 18.07.2011 #1
    Laersieh

    Laersieh Threadstarter Neuer Benutzer

    Beiträge:
    9
    Erhaltene Danke:
    0
    Registriert seit:
    18.07.2011
    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:
     
  2. the_alien, 18.07.2011 #2
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    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.
     
  3. Laersieh, 18.07.2011 #3
    Laersieh

    Laersieh Threadstarter Neuer Benutzer

    Beiträge:
    9
    Erhaltene Danke:
    0
    Registriert seit:
    18.07.2011
    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.
     
  4. the_alien, 18.07.2011 #4
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    Rufst du die reset Methode auf sobald gescrollt wird?
     
  5. Laersieh, 18.07.2011 #5
    Laersieh

    Laersieh Threadstarter Neuer Benutzer

    Beiträge:
    9
    Erhaltene Danke:
    0
    Registriert seit:
    18.07.2011
    Nein, beim OnItemClick(...) des OnItemClickListeners.

    Wie kann ich das beim Scrollen aufrufen ? Ein Beispiel wie ich das damit lösen könnte ?
     
  6. the_alien, 18.07.2011 #6
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    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.
     
  7. Laersieh, 18.07.2011 #7
    Laersieh

    Laersieh Threadstarter Neuer Benutzer

    Beiträge:
    9
    Erhaltene Danke:
    0
    Registriert seit:
    18.07.2011
    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'. (?)
     
  8. the_alien, 18.07.2011 #8
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    Woher kommt denn "value1"?
     
  9. swordi, 18.07.2011 #9
    swordi

    swordi Gewerbliches Mitglied

    Beiträge:
    3,389
    Erhaltene Danke:
    441
    Registriert seit:
    09.05.2009
    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
     
  10. cypressious, 18.07.2011 #10
    cypressious

    cypressious Android-Hilfe.de Mitglied

    Beiträge:
    80
    Erhaltene Danke:
    22
    Registriert seit:
    04.12.2010
    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.
     
  11. swordi, 18.07.2011 #11
    swordi

    swordi Gewerbliches Mitglied

    Beiträge:
    3,389
    Erhaltene Danke:
    441
    Registriert seit:
    09.05.2009
    gibt es bei einem listview element einen checked state?? ich glaube das funktioniert so nicht
     
  12. cypressious, 19.07.2011 #12
    cypressious

    cypressious Android-Hilfe.de Mitglied

    Beiträge:
    80
    Erhaltene Danke:
    22
    Registriert seit:
    04.12.2010
    nicht checked, aber pressed
     
  13. the_alien, 19.07.2011 #13
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    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?
     
  14. swordi, 19.07.2011 #14
    swordi

    swordi Gewerbliches Mitglied

    Beiträge:
    3,389
    Erhaltene Danke:
    441
    Registriert seit:
    09.05.2009

    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
     
  15. Laersieh, 19.07.2011 #15
    Laersieh

    Laersieh Threadstarter Neuer Benutzer

    Beiträge:
    9
    Erhaltene Danke:
    0
    Registriert seit:
    18.07.2011
    '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:
     
  16. the_alien, 19.07.2011 #16
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    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.
     
  17. Laersieh, 19.07.2011 #17
    Laersieh

    Laersieh Threadstarter Neuer Benutzer

    Beiträge:
    9
    Erhaltene Danke:
    0
    Registriert seit:
    18.07.2011
    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: 19.07.2011
  18. the_alien, 19.07.2011 #18
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    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
     
  19. Laersieh, 19.07.2011 #19
    Laersieh

    Laersieh Threadstarter Neuer Benutzer

    Beiträge:
    9
    Erhaltene Danke:
    0
    Registriert seit:
    18.07.2011
    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 ?
     
  20. the_alien, 19.07.2011 #20
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    Genau! Oder bei jedem Zeichnen den Hintergrund setzen...
    Code:
    if(isSelected(position) {
        view.setBackground(R.color.selected);
    }else{
        view.setBackground(R.color.normal);
    }
     
    Laersieh bedankt sich.

Diese Seite empfehlen