Das ausgewählte Element von Android ListView bleibt hervorgehoben

76

Ich habe eine XMLmit zwei ListView, eine mit einer Liste von Clients, die von einer ausgewählten Abfrage ( lv_cli) gefüllt sind, und die andere mit den Details des ausgewählten Clients ( lv_cli_det). Ich möchte den Kunden in der lv_cliZeit, in der lv_cli_detdie Details angezeigt werden, ausgewählt lassen .

XML:

<ListView
    android:id="@+id/cli_lista"
    android:layout_width="512dp"
    android:layout_height="wrap_content"
    android:fadeScrollbars="false"
    >
</ListView>

<ListView
    android:id="@+id/cli_lista_det"
    android:layout_width="512dp"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@+id/cli_lista"
    android:fadeScrollbars="false" >
</ListView>

Java:

Cursor cursor = db.rawQuery("Select NrCl||';'||Nome From Clientes", null);
final ListView t = (ListView)findViewById(R.id.cli_lista);
ArrayAdapter<String> myarrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, listItems);
t.setAdapter(myarrayAdapter);

final ListView td = (ListView)findViewById(R.id.cli_lista_detalhe);
final ArrayAdapter<String> myarrayAdapter2 = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, listItems2);

t.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        String item = ((TextView)view).getText().toString();
        String[] strArray = item.split("\\;");

        cli.load(strArray[0].toString());
        td.setAdapter(myarrayAdapter2);
        listItems2.clear();
        listItems2.add("Nome: " + cli.getNome());
        listItems2.add("Morada: " + cli.getMorada());
        listItems2.add("Localidade: " + cli.getLoca());
        listItems2.add("Código Postal: " + cli.getCp());
        listItems2.add("Pais: " + cli.getPais());
        listItems2.add("Nif: " + cli.getNif());
        listItems2.add("Tel: " + cli.getTel());
        listItems2.add("Tlm: " + cli.getTlm());
        listItems2.add("Tipo Preço: " + cli.getTipoPvn());
        listItems2.add("Cond. Pagamento: " + cli.getCpg());
        listItems2.add("Obs: " + cli.getObs());
        td.setAdapter(myarrayAdapter2);
        myarrayAdapter2.notifyDataSetChanged(); 
    }
});
Celta
quelle
Zeigen Sie Ihren Code. du hast fragment benutzt oder was ??
Avinash Kumar Pankaj
einfach rückwärts machen. Wie macht man Code für Highligh Listview? Postleitzahl hier ..
Dhaval Parmar

Antworten:

134

Fügen Sie die folgende Zeile in das Layout Ihres Listenansichtselements ein, um die Farbe des Listenansichtselements beim Drücken beizubehalten:

android:background="@drawable/bg_key"

Dann definieren Sie bg_key.xmlin drawableOrdner wie folgt:

<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item 
        android:state_selected="true"
        android:drawable="@color/pressed_color"/>
    <item
        android:drawable="@color/default_color" />
</selector>

Fügen Sie dies schließlich in Ihre ListView onClickListener:

listView.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,long arg3) {
        view.setSelected(true);
        ... // Anything
    }
});

Auf diese Weise wird immer nur ein Element farblich ausgewählt. Sie können Ihre Farbwerte folgendermaßen definieren res/values/colors.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="pressed_color">#4d90fe</color>
    <color name="default_color">#ffffff</color>
</resources>
Neoh
quelle
Fehler: Fehler: Es wurde keine Ressource gefunden, die dem angegebenen Namen entspricht (bei 'drawable' mit dem Wert '@ drawable / press_color'). Fehler: Fehler: Es wurde keine Ressource gefunden, die dem angegebenen Namen entspricht (bei 'drawable' mit dem Wert '@ color / default_color').
Celta
2
Der Farbname ist nur ein Beispiel. Es zeigt, dass Sie entweder 1) ein 9-Patch-Farbbild im PNG-Format erstellen und es dann in einen Zeichenordner legen können oder 2) die Farbe in res / values ​​/ color.xml definieren und dann mit android aufrufen können: drawable = "@ Farbe / Farbe ". Sie müssen zuerst die Datei colours.xml erstellen, wenn sie nicht vorhanden ist.
Neoh
Funktioniert die erste Listenansicht ordnungsgemäß? Sie müssen das gleiche für die Layout-XML der zweiten Listenansicht und deren onClickListener ()
tun
Ich brauche nicht die zweite Listenansicht, um wie die erste zu handeln
Celta
Ich sehe nur eine listView td in Ihrem Code definiert. Sollten Sie nicht zwei Listenansichten definieren?
Neoh
165

Ich habe den richtigen Weg gefunden. Es ist sehr einfach. Beschreiben Sie in der Ressource Folgendes:

android:choiceMode="singleChoice"
android:listSelector="#666666"

(oder Sie können einen Ressourcenlink anstelle eines Farbwerts angeben)

Programmatisch:

listView.setSelector(Drawable selector);
listView.setSelector(int resourceId);
listView.setChoiceMode(int mode);

Der Modus kann einer der folgenden sein: AbsListView.CHOICE_MODE_SINGLE, AbsListView.CHOICE_MODE_MULTIPLE, AbsListView.CHOICE_MODE_NONE (Standard)

(AbsListView ist der abstrakte Vorfahr für die ListView-Klasse)

PS-Manipulationen mit onItemClick und das Ändern des Ansichtshintergrunds sind bankrott, da eine Ansicht selbst ein temporäres Objekt ist. Daher dürfen Sie keine Ansicht verfolgen.

Wenn unsere Liste lang genug ist, werden die Ansichten, die mit ausgeblendeten Elementen verknüpft sind, aus der Hierarchie entfernt und neu erstellt, wenn diese Elemente erneut angezeigt werden (mit zwischengespeicherten Anzeigeoptionen, z. B. Hintergrund). Die von uns verfolgte Ansicht ist jetzt keine tatsächliche Ansicht des Elements, und das Ändern des Hintergrunds hat nichts mit der tatsächlichen Elementansicht zu tun. Als Ergebnis haben wir mehrere Elemente ausgewählt.

AJG
quelle
15
Dies sollte als Antwort akzeptiert werden. Einfach und sehr effizient.
Chostakovitch
2
Einfache und elegante Antwort!
Dunkler Ritter
1
Obwohl andere Antworten richtig sind, ist diese sauber und einfach.
Velval
1
Ich möchte, dass eines der listView-Elemente standardmäßig ausgewählt wird. Wie kann ich das tun?
Apurva
3
@AJG Wenn ich den Modus auf Single in Multiple ändere, funktioniert das nicht. Es wird nur das letzte ausgewählte Element farbig angezeigt. Aber ich möchte das. Wenn ich drei Elemente auswähle, müssen alle drei farbig sein.
Ajay Sharma
37
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

            for (int j = 0; j < adapterView.getChildCount(); j++)
                adapterView.getChildAt(j).setBackgroundColor(Color.TRANSPARENT);

            // change the background color of the selected element
            view.setBackgroundColor(Color.LTGRAY);
});

Vielleicht möchten Sie das aktuell ausgewählte Element mithilfe des Index i in einer globalen Variablen speichern.

Chris623
quelle
6
Etwas Seltsames passiert, wenn die Tastatur angezeigt wird. Es erfolgt eine Mehrfachauswahl.
Ricardo
1
Dies ist falsch, da die Listenansicht, um Speicherplatz zu sparen, anscheinend alle 10 Elemente dieselben Ansichten verwendet (oder wahrscheinlich jedes n Element, wobei n größer ist als die Anzahl der auf dem Bildschirm sichtbaren Elemente). Deshalb erfolgt eine Mehrfachauswahl.
Marco
13

Einfach ausgedrückt: Wenn Sie die Listenansicht in einer XML-Datei verwenden, verwenden Sie diese Attribute in Ihrer Listenansicht.

android:choiceMode="singleChoice"
android:listSelector="#your color code"

Wenn Sie XML nicht verwenden, programmgesteuert

listview.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
listview.setSelector(android.R.color.holo_blue_light);
Ashana.Jackol
quelle
10
Du bist etwas spät dran. Die Antwort von AJG liegt mehr als ein Jahr vor Ihrer Antwort und ist vollständiger.
SMBiggs
5

Sie benötigen einen Selektor wie folgt:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<!-- State when a row is being pressed, but hasn't yet been activated (finger down) -->
<item android:drawable="@color/app_primary_color_light" android:state_pressed="true" />

<!-- Used when the view is "activated". -->
<item android:drawable="@color/app_primary_color" android:state_activated="true" />

<!-- Default, "just hangin' out" state. -->
<item android:drawable="@android:color/transparent" /></selector>

Und dann android:choiceMode="singleChoice"auf Ihre ListView setzen.

Крум Илиев
quelle
Vergessen Sie nicht, die Zeile hinzuzufügen: android:listselector="@drawable/my_selector"in Ihrer ListView!
SMBiggs
Diese Lösung funktioniert für mich in Android Kitkat 19 Vielen Dank
DoctorDoom
2

Aus dem Beispiel von Avinash Kumar Pankaj

View v;

dann bei oncreate Methode

v = new View(getActivity());

und dann onlistitemclick Methode, die ich geschrieben habe

public void onListItemClick(ListView listView, View view, int position,
       long id) {
   v.setBackgroundResource(0);
   view.setBackgroundResource(R.color.green);
   v = view;
}

Es hat bei mir funktioniert. Vielen Dank.

ich ersetzte

v = new View(getActivity());

zu

v = new View(this);

und der Code funktionierte gut.

Es sind auch die XML-Dateien 'Farben' und 'bg_key' aus früheren Beispielen sowie das ListView-Attribut android erforderlich: background = "@ drawable / bg_key"

Mauro

rmunn
quelle
2

* Bitte stellen Sie sicher, dass sich in Ihrem Stammlayout des Listenansichtscontainers keine Welligkeit befindet

Fügen Sie diese Zeile Ihrer Listenansicht hinzu

android:listSelector="@drawable/background_listview"

Hier ist die Datei "background_listview.xml"

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/white_background" android:state_pressed="true" />
<item android:drawable="@color/primary_color" android:state_focused="false" /></selector>

die Farben, die in der Datei background_listview.xml verwendet wurden:

<color name="primary_color">#cc7e00</color>
<color name="white_background">#ffffffff</color>

danach

(Das angeklickte Element enthält eine orange Farbe, bis Sie auf ein anderes Element klicken.)

ShahinFasihi
quelle
1

Eine Möglichkeit, dies zu tun, besteht darin, die aktuell ausgewählte Position in Ihrer Aktivität zu verfolgen:

@Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position,
            long arg3) {
        currentPosition = position
        lv_cli.notifyDataSetChanged();
    }

Stellen Sie nun sicher, dass Sie dem übergeordneten Layout (linearLayout, boxLayout, relativeLayout usw.) Ihres Listenelements eine ID zuweisen.

Dann können Sie in Ihrer ListView Folgendes tun:

layoutBackground = (LinearLayout) convertView.findViewById(R.id.layout_background);

if (YourActivity.this.currentPosition == position) {
    layoutBackground.setBackgroundColor(YourActivity.this.getResources().getColor(R.color.hilight_color));
} else{
    layoutBackground.setBackgroundResource(R.drawable.list_item_drawable);
}

Grundsätzlich legen Sie die helle Farbe nur als Hintergrund für das Layout fest, wenn sie Ihrer aktuell ausgewählten Position entspricht. Beachten Sie, wie ich eine zeichnbare Hintergrundressource einstelle, wenn das Element nicht ausgewählt ist. Dies könnte in Ihrem Fall anders sein (da Sie keinen Code gepostet haben). In meinem Fall ist dieses Zeichenelement ein Wahlschalter, der sicherstellt, dass der Gegenstand beim Drücken gut beleuchtet ist.

HINWEIS: Dieser einfache Code verwendet keinen Ansichtshalter, aber ich empfehle wirklich, einen zu verwenden.

Tristan Vanderaerden
quelle
0

Verwenden Sie stattdessen die ID:

Dies ist die einfachste Methode, die auch bei langen Listen ausgeführt werden kann:

public View getView(final int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    Holder holder=new Holder();
    View rowView;
    rowView = inflater.inflate(R.layout.list_item, null);
    //Handle your items.
    //StringHolder.mSelectedItem is a public static variable.
    if(getItemId(position)==StringHolder.mSelectedItem){
        rowView.setBackgroundColor(Color.LTGRAY);

    }else{
        rowView.setBackgroundColor(Color.TRANSPARENT);
    }
    return rowView;
}

Und dann in Ihrem Onclicklistener:

list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            StringHolder.mSelectedItem = catagoryAdapter.getItemId(i-1);
            catagoryAdapter.notifyDataSetChanged();
.....
Wasiun A. Khan
quelle