2012-09-26 14 views
9

So che sembra molto semplice e ci sono domande a riguardo. Ma nessuno di questi potrebbe risolvere il mio problema. Quindi qui si va:Cambia colore di sfondo di un elemento in Android ListActivity onListItemClick

voglio cambiare il colore di una voce di elenco di sfondo in un ListActivity quando l'utente fa clic su di esso, e cambiare di nuovo al colore originale quando l'utente fa clic di nuovo (per esempio selezionare/deselezionare voce sorta di sguardo)

Ho provato a utilizzare getChildAt, funziona perfettamente se ho tutti gli elementi visibili in una schermata senza dover scorrere.

Codice:

getListView().getChildAt(position).setBackgroundColor(Color.CYAN); 

Il problema inizia quando ho più elementi nella lista e l'utente deve scorrere attraverso di loro. Una volta modificato lo sfondo per un oggetto, il colore di sfondo viene visualizzato sugli elementi appena visibili mentre scorro. Inoltre, getChildAt(position) restituisce null (e quindi un NullPointerException) quando si fa nuovamente clic sull'elemento.

Qualcuno può aiutarmi con un semplice codice che mi aiuti a cambiare il colore di sfondo di un elemento della lista?

Grazie in anticipo!

+0

Penso che questo argomento vi aiuterà a farlo. http://stackoverflow.com/questions/2217753/changing-background-color-of-listview-items-on-android – thiagolsilva

risposta

5

Sicuro. Lo farei nel metodo getView() di una personalizzata ListAdapter.

MyAdapter extends SimpleAdapter { 
    private ArrayList<Integer> coloredItems = new ArrayList<Integer>(); 

    public MyAdapter(...) { 
     super(...); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View v = super.getView(position, convertView, parent); 

     if (coloredItems.contains(position)) { 
      v.setBackgroundColor(Color.CYAN); 
     } else { 
      v.setBackgroundColor(Color.BLACK); //or whatever was original 
     } 

     return v; 
    } 
} 

Aggiornamento coloredItems quando un elemento della lista viene cliccato.

@Override 
public void onListItemClick(ListView l, View v, int position, long id) { 
    if (coloredItems.contains(position)) { 
     //remove position from coloredItems 
     v.setBackgroundColor(Color.BLACK); //or whatever was original 
    } else { 
     //add position to coloredItems 
     v.setBackgroundColor(Color.CYAN); 
    } 
} 
+0

Impressionante! Ha funzionato perfettamente! Ho avuto difficoltà a cercare di capire la soluzione. La tua risposta è stata molto utile. Vorrei poterti dare due voti ... :) Grazie ancora! :) –

+0

Sei il benvenuto! – heycosmo

+0

dopo poche ore di vicoli ciechi mi hai mostrato la strada giusta, ben fatto uomo! –

1

Quello che faccio è creare un file xml chiamato i_e_list_background e inserirlo nella cartella drawable.

L'XML assomiglia a questo:

<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:drawable="@color/list_selected" android:state_pressed="true" /> 
    <item android:drawable="@android:color/white" /> 
</selector> 

E nel codice XML per l'elemento della ListView ho messo questo XML come elementi di sfondo cioè

item.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      style="@style/Fill" 
      android:background="@drawable/list_background"> 

    <!-- Your layout here --> 
</RelativeLayout> 

style = @ style/Fill è solo una scorciatoia creata per android: layout_height = "match_parent" e android: layout_width = "match_parent

Poi nel onListItemCLick:

public void onListItemClick(ListView l, View v, int position, long id) { 
    v.setPressed(!v.isPressed) //Toggle between colors of the view 
} 
+0

Grazie per l'aiuto! Ma hai due problemi con questa soluzione: 1) Puoi selezionare solo un elemento alla volta, se provi a selezionare un altro elemento il primo automaticamente perde il suo colore di sfondo. 2) Se si seleziona un elemento, scorrere verso il basso e quindi scorrere di nuovo verso l'alto, ciò che viene visualizzato è che l'elemento selezionato non ha alcun colore di sfondo ora! :( Si prega di aiuto Grazie –

+2

Sì, è necessario modificare il metodo 'getView' del ListAdapter per mantenere tale stato (vedere la mia risposta sotto). Perché ListView riutilizza le Viste articolo, un elemento che appare in alto (dopo una pergamena) può ereditare tratti da un oggetto lasciato in basso a meno che tali tratti non vengano ripristinati in 'getView'. – heycosmo

+0

@heycosmo: Cosa succede se non utilizzo il mio ListAdapter? Perché sto usando un SimpleAdapter. ? –

0

questo è come ho fatto:

creare una variabile globale View ColoredView; poi quando si setOnItemClickListener per la vostra ListView, fare questo:

MenuList.setOnItemClickListener(new OnItemClickListener() { 

      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       if (ColoredView != null) 
        ColoredView.setBackgroundColor(Color.WHITE); //original color 

       view.setBackgroundColor(Color.BLUE); //selected color 
       ColoredView = view; 
      } 
     }); 

E 'il modo più semplice, a mio parere.

2

Se avete a che fare con ListFragment allora questo codice sarà utile,

@Override 
    public void onViewCreated(View view, Bundle savedInstanceState) { 
     super.onViewCreated(view, savedInstanceState); 
     if (view != null) { 
      getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); 
      getListView().setDescendantFocusability(ListView.FOCUS_AFTER_DESCENDANTS); 
      catagoryValueListView=getListView(); 
      catagoryValueListView.setOnItemClickListener(new OnItemClickListener() { 

      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       if (ColoredView != null) 
        ColoredView.setBackgroundColor(Color.WHITE); //original color 

       view.setBackgroundColor(Color.BLUE); //selected color 
       ColoredView = view; 
            } 
     }); 
    } 

} 
+0

Si prega di aggiornare la risposta e di inserire il codice all'interno dei tag del codice. –

0

Grazie HeyCosmo. la tua soluzione ha risolto il mio problema.

Non ho idea del motivo per cui dobbiamo impostare lo sfondo in 2 punti.

1. GetView dell'adattatore()

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    .... 
    .... 
    .... 
     if(arrayBools[position]) { 
      view.setBackgroundColor(Common.colorBkgroundSelected); 
     } 
     else{ 
      view.setBackgroundColor(Common.colorBkgroundNormal);    
     } 
    .... 
    .... 
    .... 
} 

2. onListItemClick di ListActivity().

@Override 
protected void onListItemClick(ListView l, View v, int position, long id) { 
     super.onListItemClick(l, v, position, id);  
     arrayBools[position] = (arrayBools[position] ? false : true); 

    if(arrayBools[position]) { 
     v.setBackgroundColor(colorBkgroundSelected); 
    } 
    else{ 
     v.setBackgroundColor(colorBkgroundNormal);   
    }  
} 
1

Semplicemente si può fare come questo in onListItemClick metodo

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

    for (int a = 0; a < l.getChildCount(); a++) { 
     l.getChildAt(a).setBackgroundColor(Color.TRANSPARENT); 
    } 

    ColorDrawable colorDrawable1 = new ColorDrawable(
      Color.parseColor("#A0A3A0")); 
    v.setBackgroundDrawable(colorDrawable1); 

    if (position == 0) { 
     Intent i = new Intent(MainActivity.this, NewActivity.class); 

     startActivity(i); 
    } 

} 
Problemi correlati