web-dev-qa-db-de.com

Hintergrundfarbe der ListView-Elemente auf Android ändern

Wie kann ich die Hintergrundfarbe von ListView-Elementen pro Element ändern? Wenn ich Android:backgroundColor im ListView-Elementlayout verwende, kann ich dies erreichen, jedoch ist der Listenselektor nicht mehr sichtbar. Ich kann den Selektor wieder sichtbar machen, indem Sie drawSelectorOnTop auf true setzen. Der Selektor überlagert dann das gesamte Element.

Irgendwelche Ideen, wie man diese Hintergrundfarben ändert und den Selektor behält?

PS Ich möchte den Selector lieber nicht selbst ändern.

BEARBEITEN: Autoren von GMail haben genau das erreicht, es ist also durchaus möglich.

68
Marek Stój

Sie müssen für jede Farbe, die Sie verwenden möchten, einen anderen Zeichnungsstatus erstellen. 

Zum Beispiel: list_selector_read.xml und list_selector_unread.xml

Alles, was Sie tun müssen, ist alles transparent zu setzen, außer dem Android:state_window_focused="false"-Element. 

Wenn Sie dann Ihre Liste zeichnen, rufen Sie setBackgroundResource(R.drawable.list_selector_unread/read) für jede Zeile auf. 

Sie können überhaupt keinen listSelector in der ListView setzen. Dadurch wird die Standardauswahl für Ihre Android-Variante beibehalten.

36
Hawkee

Dies ist eine Modifikation basierend auf dem obigen Code, einem einfachsten Code:

private static int save = -1;

public void onListItemClick(ListView parent, View v, int position, long id) { 

    parent.getChildAt(position).setBackgroundColor(Color.BLUE);

    if (save != -1 && save != position){
        parent.getChildAt(save).setBackgroundColor(Color.BLACK);
    }

    save = position;                

}

Ich hoffe du findest es nützlich

schöne Grüße!

25

Ok, ich habe es so gemacht:

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

YMMV!

23
Adam

Niemand schien irgendwelche Beispiele dafür zu geben, dies allein mit einem Adapter zu tun. Daher dachte ich, ich würde mein Code-Snippet zum Anzeigen von ListViews veröffentlichen, bei denen das Element "curSelected" einen anderen Hintergrund hat:

final ListView lv = (ListView)findViewById(R.id.lv);
lv.setAdapter(new BaseAdapter()
{
    public View getView(int position, View convertView, ViewGroup parent)
    {
        if (convertView == null)
        {
            convertView = new TextView(ListHighlightTestActivity.this);
            convertView.setPadding(10, 10, 10, 10);
            ((TextView)convertView).setTextColor(Color.WHITE);
        }

        convertView.setBackgroundColor((position == curSelected) ? 
            Color.argb(0x80, 0x20, 0xa0, 0x40) : Color.argb(0, 0, 0, 0));
        ((TextView)convertView).setText((String)getItem(position));

        return convertView;
    }

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

    public Object getItem(int position)
    {
        return "item " + position;
    }

    public int getCount()
    {
        return 20;
    }
});

Dies war immer eine hilfreiche Vorgehensweise für mich, wenn sich das Erscheinungsbild von Listenelementen dynamisch ändern muss.

11
ubzack
mAgendaListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//view.setBackgroundColor(Color.RED);

for(int i=0; i<parent.getChildCount(); i++)
{
     if(i == position)
     {
               parent.getChildAt(i).setBackgroundColor(Color.BLUE);
     }
     else
     {
               parent.getChildAt(i).setBackgroundColor(Color.BLACK);
     }

 }
8
Mbolland

der einfachste Weg ist dies. In Ihrem ListArrayAdapter tun Sie dies einfach

if(your condition here) rowView.setBackgroundColor(Color.parseColor("#20FFFFFF"));

nicht zu kompliziert

7
OWADVL

Aus dem Quellcode von Android's 2.2 Email App:

<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:state_window_focused="false" Android:state_selected="true"
        Android:drawable="@Android:color/transparent" />
    <item Android:state_selected="true"
        Android:drawable="@Android:color/transparent" />
    <item Android:state_pressed="true" Android:state_selected="false"
        Android:drawable="@Android:color/transparent" />
    <item Android:state_selected="false"
        Android:drawable="@color/message_item_read" />
</selector>

Nichts mehr zu sagen...

7
ThePCWizard

Einfacher Code zum Ändern des gesamten Layouts des Elements (benutzerdefinierte Listenansicht erweitert den Baseadapter):

lv.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {

            RelativeLayout layout=(RelativeLayout) arg1.findViewById(R.id.rel_cell_left);
            layout.setBackgroundColor(Color.YELLOW);



        }
    });
5

Wollten Sie die Hintergrundfarbe der benutzerdefinierten Listenelemente ändern, wenn Sie darauf klicken?

Wenn ja:

Sie fügen einfach den folgenden Code zu Ihrem Listenansicht-Layout in XML hinzu.


Android: drawSelectorOnTop = "true" Android: listSelector = "@ Android: drawable/list_selector_background"


Die Listenauswahl hier verwendet die Standardauswahl, die eine dunkelgraue Farbe hat ..__ Sie können Ihre eigene Zeichenfunktion erstellen und sie wie oben der Listenauswahl zuweisen.

Hoffe das ist es was du wolltest.

4
PrasadW

Dem Weg sehr langsam im Laufen folgen

mAgendaListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//view.setBackgroundColor(Color.RED);

for(int i=0; i<parent.getChildCount(); i++)
{
     if(i == position)
     {
               parent.getChildAt(i).setBackgroundColor(Color.BLUE);
     }
     else
     {
               parent.getChildAt(i).setBackgroundColor(Color.BLACK);
     }

 }

Ersetzt durch Folgendes

int pos = 0;
int save = -1;
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {
            //Always set the item clicked blue background
            view.setBackgroundColor(Color.BLUE);

            if (pos == 0) {
                if (save != -1) {
                    parent.getChildAt(save).setBackgroundColor(Color.BLACK);
                }
                save = position;
                pos++;
                Log.d("Pos = 0", "Running");

            } else {
                parent.getChildAt(save).setBackgroundColor(Color.BLACK);
                save = position;
                pos = 0;
                Log.d("Pos # 0", "Running");
            }
2
PrDoHung

Werfen Sie einen Blick auf List14 Beispiel . In getView() können Sie convertView.setBackgroundDrawable() für jeden Eintrag aufrufen. Sie könnten einen Klassenmitgliedszähler haben, um zu entscheiden, mit welchem ​​Hintergrund er aufgerufen wird, um beispielsweise wechselnde Hintergründe zu erhalten.

1
Heikki Toivonen

Das beste Tutorial dazu finden Sie hier

Schlüsselbereiche:

  1. Rufen Sie sicher view.setSelected(true) in onItemClick auf, andernfalls können Sie den ausgewählten Elementhintergrund nicht sehen
  2. Behalten Sie die Reihenfolge der Zustände in Ihrem Selector bei, andernfalls werden unvorhersehbare Verhaltensweisen in Hintergrundfarben angezeigt (state_selected gefolgt von state_pressed)
1
Mohsen Afshin

In der Listenansicht können Sie Android hinzufügen: listselector = Farbname, den Sie möchten.

das funktioniert gut in meiner App.

1

Durch das Ändern eines Codes von Francisco Cabezas erhielt ich Folgendes:

private int selectedRow = -1;

...

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    parent.getChildAt(position).setBackgroundResource(R.color.orange);
    if (selectedRow != -1 && selectedRow != position) {
        parent.getChildAt(selectedRow).setBackgroundResource(R.color.black);
    }
    selectedRow = position;
1
CoolMind

Ich habe alle obigen Antworten ausprobiert .. keiner hat für mich funktioniert. Dies hat letztendlich funktioniert und wird in meiner Anwendung verwendet. Es werden gelesene/ungelesene Listenelemente-Farben bereitgestellt, während Listselector-Stile für beide Status beibehalten werden: 

<ListView
                Android:id="@+id/list"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                Android:listSelector="@drawable/selectable_item_background_general"
                Android:drawSelectorOnTop="true"
                Android:fadingEdge="none"
                Android:scrollbarStyle="outsideOverlay"
                Android:choiceMode="singleChoice" />

selectable_item_background_general.xml:  

<selector xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:exitFadeDuration="@Android:integer/config_mediumAnimTime">
    <item Android:state_pressed="false" Android:state_focused="true" Android:drawable="@drawable/bg_item_selected_drawable" />
    <item Android:state_pressed="true" Android:drawable="@drawable/bg_item_selected_drawable" />
    <item Android:drawable="@Android:color/transparent" />
</selector>

bg_item_selected_drawable.xml:  

<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <solid Android:color="#12000000" />
</shape>

notification_list_itemlayout.xml:  

<RelativeLayout 
            xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:id="@+id/rowItemContainer"
            Android:layout_width="fill_parent"
            Android:layout_height="wrap_content">

    <RelativeLayout 
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:padding="8dp"
        Android:paddingLeft="16dp"
        Android:paddingStart="16dp"
        Android:paddingRight="16dp"
        Android:paddingEnd="16dp">

            <ImageView
                Android:id="@+id/imgViewIcon"
                Android:layout_width="60dp"
                Android:layout_height="60dp"
                Android:src="@drawable/cura_logo_symbol_small"
                Android:layout_alignParentLeft="true"
                Android:layout_alignParentStart="true"
                Android:layout_marginRight="8dp"
                Android:layout_marginEnd="8dp" />
            <TextView
                Android:id="@+id/tvNotificationText"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:layout_alignTop="@+id/imgViewIcon"
                Android:layout_toRightOf="@+id/imgViewIcon"
                Android:layout_toEndOf="@+id/imgViewIcon"
                Android:textSize="@dimen/subtitle"
                Android:textStyle="normal" />
            <TextView
                Android:id="@+id/tvNotificationTime"
                Android:layout_width="fill_parent"
                Android:layout_height="wrap_content"
                Android:layout_marginTop="1dip"
                Android:layout_below="@+id/tvNotificationText"
                Android:layout_toRightOf="@+id/imgViewIcon"
                Android:layout_toEndOf="@+id/imgViewIcon"
                Android:textSize="@dimen/subtitle" />
        </RelativeLayout>
</RelativeLayout>

Zum Schluss in deinem Adapter:  

if (!Model.Read)
    rowItemContainer.SetBackgroundColor (Android.Graphics.Color.ParseColor ("#FFFDD0")); // unread color
else
    rowItemContainer.SetBackgroundColor (Android.Graphics.Color.White); // read color
0

Du kannst das.

 final List<String> fruits_list = new ArrayList<String>(Arrays.asList(fruits));

    // Create an ArrayAdapter from List
    final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>
            (this, Android.R.layout.simple_list_item_1, fruits_list){
        @Override
        public View getView(int position, View convertView, ViewGroup parent){
            // Get the current item from ListView
            View view = super.getView(position,convertView,parent);
            if(position %2 == 1)
            {
                // Set a background color for ListView regular row/item
                view.setBackgroundColor(Color.parseColor("#FFB6B546"));
            }
            else
            {
                // Set the background color for alternate row/item
                view.setBackgroundColor(Color.parseColor("#FFCCCB4C"));
            }
            return view;
        }
    };

    // DataBind ListView with items from ArrayAdapter
    lv.setAdapter(arrayAdapter);
}

}

0
Fouziya Parveen

Wenn die Variable setBackgroundColor für das onItemClick -Ereignis hinzugefügt wird, funktioniert es nur, wenn Sie es nach dem click -Ereignis setzen können.

Versuchen Sie, Debug-Code in die getView-Methode des Adapters einzufügen. Wenn Sie auf den Bildschirm klicken, wird getView erneut aufgerufen. Nachdem Sie die Hintergrundfarbe eingestellt haben, zeichnet das System den Bildschirm mit den ursprünglichen Einstellungen neu. Ich weiß nicht, warum es Ressourcen verbraucht, um den Bildschirm neu aufzubauen, wenn er angeklickt wird. Es gibt bereits eine andere Möglichkeit, das System zu benachrichtigen, um den Bildschirm bei Bedarf neu zu zeichnen.

Möglicherweise können Sie ein Kontrollflag hinzufügen, um die Hintergrundfarbe für die einzelnen Zeilen zu bestimmen, und dann die getView-Methode ändern, um die Farbe entsprechend diesem Steuerflag festzulegen. Die Hintergrundfarbe wird also geändert, wenn der Bildschirm neu gezeichnet wird.

Ich suche auch nach einer offiziellen Lösung.

0
Super169