it-swarm.com.de

Android - Das Element von ListView bleibt nach dem Anklicken hervorgehoben

Ich habe also eine Aktivität mit 2 ListView-Widgets. Wenn Sie einen Wert im ersten auswählen, wird der zweite mit Werten gefüllt, die sich auf die Auswahl in der ersten ListView beziehen. Dieser Mechanismus funktioniert problemlos, aber jetzt möchte ich, dass die Benutzerauswahl hervorgehoben wird. Ich habe eine Menge Fragen zu diesem Thema gelesen und es scheint eine Unzahl von Möglichkeiten zu geben, aber man kann es nach 4-5 Versuchen noch nicht schaffen.

Ich habe es mit der zweiten ListView mit dem Android:listSelector="#CCCCCC"-XML-Attribut zu tun, aber es scheint gelöscht zu werden, sobald eine OnItemClickListener in die Mischung eingefügt wird (wie die, die ich bei meiner ersten ListView verwende).

So weit hier ist was ich habe:

Benutzerdefinierte OnItemClickListener Ich habe beim Durchsuchen verschiedene Antworten zu diesem Thema gefunden (etwas modifiziert, um meine Informationen in die zweite ListView zu laden): 

private class ItemHighlighterListener implements OnItemClickListener {

    private View oldSelection = null;

    public void clearSelection() {
        if(oldSelection != null) {
            oldSelection.setBackgroundColor(Android.R.color.transparent);
        }
    }

    public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
        clearSelection();
        oldSelection = view;
        view.setBackgroundDrawable(view.getContext().getResources().getDrawable(R.drawable.list_selector));
        loadClubs(mXMLPortalOptions.getRegion(pos).getId());
        mClubList.setAdapter(new ArrayAdapter<String>(getApplicationContext(), R.layout.list_item_white, mClubs));
    }
}

Hier ist meine list_selector.xml-Datei: 

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <item Android:state_selected="true"><shape>
            <solid Android:color="#CCCCCC" />
        </shape></item>

    <item Android:state_selected="false"><shape>
            <solid Android:color="#FFFFFF" />
        </shape></item>

</selector>

Die Methode (OnItemClick) wird aufgerufen und ausgeführt, der Hintergrund meiner ListItem bleibt jedoch in derselben Farbe: /

Ich kann nicht glauben, dass diese einfache Aufgabe so kompliziert ist.

Wenn ich einen Code weggelassen habe, der nützlich sein könnte, oder wenn meine Frage keine Details enthält, können Sie mich darauf hinweisen, und ich werde mein Bestes geben, um mich selbst zu erklären.

36

Platzieren Sie eine Positionsvariable für das ausgewählte Element. Ändern Sie die Position in der onItemClicked()-Methode. Überprüfen Sie die ausgewählte Position in List Adapter in getView() und legen Sie den Hintergrund für das ausgewählte Element fest.

public class TestAdapter extends BaseAdapter
{
    private Context context;
    private ArrayList<TestList> testList;
    private int selectedIndex;
    private int selectedColor = Color.parseColor("#1b1b1b");

    public TestAdapter(Context ctx, ArrayList<TestList> testList)
    {
        this.context = ctx;
        this.testList = testList;
        selectedIndex = -1;
    }

    public void setSelectedIndex(int ind)
    {
        selectedIndex = ind;
        notifyDataSetChanged();
    }

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

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

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

    private class ViewHolder
    {
        TextView tv;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        View vi = convertView;
        ViewHolder holder;
        if(convertView == null)
        {
            vi = LayoutInflater.from(context).inflate(R.layout.test_list_item, null);
            holder = new ViewHolder();

            holder.tv = (TextView) vi;

            vi.setTag(holder);
        }
        else
        {
            holder = (ViewHolder) vi.getTag();
        }

        if(selectedIndex!= -1 && position == selectedIndex)
        {
            holder.tv.setBackgroundColor(Color.BLACK);
        }
        else
        {
            holder.tv.setBackgroundColor(selectedColor);
        }
        holder.tv.setText("" + (position + 1) + " " + testList.get(position).getTestText());

        return vi;
    }

}

Legen Sie nun die selectedIndex-Variable fest, wenn Sie auf ein Listenelement klicken.

public class TestActivity extends Activity implements OnItemClickListener
{
    // Implemented onItemClickListener

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id)
    {
        adapter.setSelectedIndex(position);
    }
}
61
Shaiful

Um auf Shaifuls großartige Lösung einzugehen, werden Sie vielleicht nicht in Ihrer Situation arbeiten.

Wenn Sie Ihren Code in public void onListItemClick(ListView l, View v, int index, long id) verwenden, wenn Sie Fragmente verwenden und eine Schnittstelle deklarieren müssen, anstatt OnListItemClickListener zu implementieren, oder was auch immer die IDE Fehler verursacht, müssen Sie möglicherweise auf Variablen zugreifen und Methoden statisch.

public static int selectedPosition = 0;
ArrayAdapter<Your_obj> adapter = null;

@Override
public void onListItemClick(ListView l, View v, int index, long id) {
    super.onListItemClick(l, v, index, id);

        selectedPosition = index;
        Your_adapter.setSelectedIndex(selectedPosition);
        adapter.notifyDataSetChanged();
}

Und in Deinem Adapter:

private static int selectedIndex;

//public Your_adapter...

public static void setSelectedIndex(int ind) {
    selectedIndex = ind;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    WellHolder holder = null;

    if (null == convertView) {

                //set up your "holder"
    }

    if (position == selectedIndex) {
        convertView.setBackgroundColor(convertView.getResources().getColor(R.color.cyan));
    }
    else {
        convertView.setBackgroundColor(convertView.getResources().getColor(R.color.silver));
    }

    return convertView;
}

Einige andere Unterschiede sind, dass Sie keine Variablen als "0" oder "-1" initialisieren müssen und notifyDataSetChanged () in Ihrer Aktivität aufgerufen wird.

Nochmals vielen Dank für Ihre Lösung @Shaiful. Es hat mir sicherlich dabei geholfen, Zeit zu sparen, indem ich versuchte, die Standardeinstellung von iOS für Android zu nutzen, und dabei den Selector/item/focus// etc zu vermeiden.

5
whyoz

Ich stand vor einem ähnlichen Problem. Das ist meine Lösung:

Fügen Sie zunächst Ihrer Listenansicht einen benutzerdefinierten Listen-Selector hinzu:

<ListView
    Android:id="@+id/list"
    Android:layout_width="match_parent"
    Android:layout_height="fill_parent"
    Android:listSelector="@drawable/listselector" />

In listselector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:state_accelerated="false"
        Android:drawable="@drawable/bg" />
</selector>

Und zum Schluss noch eine gezeichnete bg.xml mit der Farbe Ihres Highlights:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <solid Android:color="#33b5e6"/>
</shape>
4
zjadarka

Ich denke, die beste und einfachste Lösung ist dies. Sie nicht müssen einen Android:listSelector In der ListView selbst festlegen oder Änderungen am Adapter vornehmen. Sie nicht müssen sogar eine setSelection(position) im OnItemClickListener aufrufen, da diese automatisch behandelt wird.

  1. Auf ListView einstellen:

    Android:choiceMode="singleChoice"
    
  2. Hintergrund des Listenelements selbst festlegen:

    Android:background="?android:attr/activatedBackgroundIndicator"
    
  3. Fertig

Auf diese Weise erhalten Sie das Standardverhalten des Systems. So wird es im Standardlayout Android.R.layout.simple_list_item_activated_1 Gemacht.

3
Robyer
//create a list_itemselectorin drawable folder
//you will get the list item selected background color change once you select //the item

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

        <!-- Focused State -->
        <item Android:state_focused="true"><shape>
                <solid Android:color="#66FFFFFF" />
            </shape></item>
        <!-- Pressed State -->

        <item Android:state_pressed="true"><shape>
                <solid Android:color="@color/Black" />
            </shape></item>

        <!-- Default State -->
        <item><shape>
                <solid Android:color="@color/Black" />
            </shape></item>

    </selector>


    //create a list in layout folder
      <ListView
            Android:id="@+id/mySlidingList"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:choiceMode="singleChoice"
            Android:divider="@color/GrayHot"
            Android:dividerHeight="1dip"
            Android:listSelector="@drawable/list_itemselector"
            Android:scrollbars="none" />

// Und die Ausgabe sehen.

2
DeepakPanwar

lv.setSelector(R.drawable.highlighter);

legen Sie ein highlighter.png Bild in einen Zeichenordner
einfachste Möglichkeit, ein ausgewähltes Element in der Listenansicht hervorzuheben.

2
Supun Perera

Ich habe vor zwei Wochen danach gesucht und das Ergebnis ist, dass dies mit einem Drawable Selector nicht möglich ist. Für weitere Informationen lesen Sie diesen Beitrag im Android Developers Blog: Touch Mode

In Resume: Nur wenn Ihr Finger auf dem Bildschirm ist, wird das Element ausgewählt. 

Eine andere Möglichkeit besteht darin, zu speichern, welches Element in einer var und Paint mit Ihrem benutzerdefinierten Adapter anders als Shaiful ausgewählt wird.

2
i.masm

Um diesen Beitrag zusammenzufassen und möglicherweise in Zukunft jemand anderem zu helfen, schlage ich die Antwort vor :)

Zunächst müssen wir eine res/drawable/list_item_background.xml-Datei mit folgendem Inhalt erstellen:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item
        Android:state_activated="true"
        Android:drawable="@color/list_item_activated" />
    <item
        Android:drawable="@color/list_item_default" />
</selector>

Geben Sie natürlich Ihre Ressourcen an. Sie können auch andere <item>-Elemente mit verschiedenen Status hinzufügen, wie state_pressed, state_focused usw.

Dann sollten wir den background-Parameter wie folgt auf unser benutzerdefiniertes Listenelement ViewGroup-Element (f.i. res/layout/list_item_layout.xml) setzen:

Android:background="@drawable/list_item_background"

Der nächste Schritt ist das Ändern unserer benutzerdefinierten Adapter-Klasse. Hier ist das folgende Codefragment:

public class CustomAdapter extends BaseAdapter {
    private List<Item> items;
    private LayoutInflater itemInflater;        
    private int selectedIndex; // add this

    public CustomAdapter(Context c, List<Item> items) {
        this.items = items;
        this.itemInflater = LayoutInflater.from(c);
        selectedIndex = -1; // add this
    }

    /* add this */
    public void setSelectedIndex(int index) {
        selectedIndex = index;
        notifyDataSetChanged();
    }

    /* other adapter's stuff */

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(convertView == null) {
            convertView = itemInflater.inflate(R.layout.list_item_layout, parent, false);
        }

        // add this
        convertView.setActivated(selectedIndex != -1 && position == selectedIndex);

        /* do some stuff */

        return convertView;
    }
}

Schließlich sollten wir die Methode des setSelectedIndex(position) Adapters in der onItemClick(...) Methode von AdapterView.OnItemClickListener aufrufen.

public class YourActivity extends Activity
        implements AdapterView.OnItemClickListener {

    private CustomAdapter mCustomAdapter;

    /* activity implementation */

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        mCustomAdapter.setSelectedIndex(position);
    }
}

Nun können wir mit der richtigen Hervorhebung von Listenelementen zufrieden sein :)

P.S. Wenn Sie den Multiple-Choice-Modus in unserer Liste aktivieren möchten, platzieren Sie einfach die folgende Zeichenfolge in unserer Aktivitätsklasse, in der die listView-Instanz gespeichert ist:

listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

So erhalten wir die richtige Hervorhebung von multiple Items.

- Hoffe das hilft jemandem :)

0
Eugene Matiyuk

Es gibt eine einfache XML-Komplettlösung, die für mich funktioniert hat ..__ Definieren Sie zunächst XML-Drawable mit Auswahlcode, in dem der "normale" Status dem "ausgewählten, nicht komprimierten" visuellen Status eines Listenelements entspricht und state_pressed = true visueller Zustand "gedrückt" . Beispiel für die Datei "custom_item_selector.xml", die der blauen Auswahl von Holo ähnelt:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:state_pressed="true">
        <shape Android:shape="rectangle">
            <solid
                Android:color="#643292ff">
            </solid>
            <stroke
                Android:width="1dp"
                Android:color="#c83292ff">
            </stroke>
        </shape>
    </item>
    <item>
        <shape Android:shape="rectangle">
            <solid
                Android:color="#323292ff">
            </solid>
            <stroke
                Android:width="1dp"
                Android:color="#783292ff">
            </stroke>
        </shape>
    </item>
</selector>

(kann auch den fokussierten Zustand dort setzen) . Zweitens wende dieses xml-drawable als ListSelector von ListView an und setze den gewünschten choiceMode:

<ListView
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:id="@+id/listView"
            Android:choiceMode="singleChoice"
            Android:listSelector="@drawable/custom_item_selector"/>

Das ist alles. Sie können verschiedene visuelle Zustände für "einfach ausgewählte" und "gedrückte ausgewählte" Elemente definieren, z. B. um Objekte beim Druck heller zu machen.

0
jetc

Um die Listenelemente (Mehrfachauswahl) hervorgehoben zu halten, führen Sie die folgenden Schritte aus, wenn Sie darauf klicken (aktiviert).

1. Legen Sie den Hintergrund so fest, dass das Elementlayout als gezeichnet angezeigt wird.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:layout_width="match_parent"
        Android:layout_height="40dp"
        Android:background="@drawable/list_item_selector">

        <ImageView
            Android:id="@+id/icon"
            Android:layout_width="22px"
            Android:layout_height="22px"
            Android:layout_marginLeft="4px"
            Android:layout_marginRight="10px"
            Android:layout_marginTop="4px"
            Android:src="@mipmap/ic_launcher" >
        </ImageView>

        <TextView
            Android:id="@+id/label"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="@+id/label"
            Android:textSize="20px" >
        </TextView>
    </LinearLayout>

2. zugbarer Wahlschalter

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">

<item Android:state_pressed="true"     Android:drawable="@Android:color/holo_red_light" />

<item Android:state_activated="true" Android:drawable="@Android:color/holo_orange_dark" />

</selector>

3. Listenansicht, Mehrfachauswahl-Modus

getListView (). setChoiceMode (ListView.CHOICE_MODE_MULTIPLE);

Wenn gedrückt:  enter image description here

Das folgende Bild zeigt, wenn der Benutzer mehrere Listenelemente ausgewählt hat.

Bei Aktivierung:  enter image description here

0
Annada

Wenn Sie ein drawable zum Anzeigen von listItem Highlighted verwenden können, sollten Sie folgenden Code verwenden:

listView.setSelector(R.drawable.bg_image);

Es klappt.

0
Suresh Sharma