java - tamaño - Cree un ListView con filas seleccionables/cambie el color de fondo de las filas de ListView cuando haga clic
personalizar listview android (1)
Solución
La solución a este problema es muy simple. Necesitamos agregar un OnItemClickListener
a nuestro ListView
para escuchar los clics y responder en consecuencia.
Entonces, en el método onCreate()
, una vez que se ha asegurado de que el conjunto de datos no esté vacío, va a querer onItemClick()
método onItemClick()
para escuchar el clic y cambiar el color. También querrá hacer un seguimiento del elemento que seleccionó para los pasos posteriores, así que agregue public int selectionId = -1;
en la parte superior de tu clase. Además, deberá informar al ListAdapter
que ha cambiado algo llamando a ((SimpleAdapter) getListAdapter()).notifyDataSetChanged()
.
if(receiverList.size() != 0) {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int index, long id) {
view.setBackgroundColor(Color.RED);
TextView receiverIdTextView = (TextView) view.findViewById(R.id.receiverId);
selectionId = Integer.valueOf(receiverIdTextView.getText().toString());
((SimpleAdapter) getListAdapter()).notifyDataSetChanged();
}
});
SimpleAdapter adapter = getNewAdapter();
setListAdapter(adapter);
}
¡Estupendo! Ahora tenemos un sistema en funcionamiento que cambiará el color de la fila que toque. Pero no hemos terminado todavía. Necesitamos asegurarnos de que la selección previa vuelva al color normal.
Para esto, vamos a utilizar la anulación del SimpleAdapter
getView()
, que se llama cada vez que ListView
va a dibujar los elementos que se muestran en él.
Solo muestra los elementos que necesita, los que puede ver. No representa los que están arriba o debajo de su pantalla. Por lo tanto, si tiene 200 elementos en un ListView
, solo 5 o 6, según el tamaño de la pantalla y el tamaño de los elementos, se procesarán a la vez.
Para anular el método getView()
, vaya hasta donde inicialice el adapter
y cambie el código a este:
SimpleAdapter adapter = new SimpleAdapter(MainActivity.this,receiverList, R.layout.receiver_entry, new String[] { "receiverId","receiverName", "fullPath"}, new int[] {R.id.receiverId, R.id.receiverName, R.id.fullPath}) {
@Override
public View getView (int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView receiverIdTextView = (TextView) view.findViewById(R.id.receiverId);
if(receiverIdTextView.getText().toString().equals(String.valueOf(selectionId))) {
view.setBackgroundColor(Color.RED);
} else {
view.setBackgroundColor(Color.WHITE);
}
return view;
}
};
Cada vez que se dibuja una de las filas, dado que se getView()
, ListView
comprobará si la view
actual tiene la identificación de la fila que seleccionó. Si no lo hace, cambiará el color de fondo a blanco. Si lo hace, cambiará el color de fondo a rojo.
¡Y voilá! ¡Eso es! Ahora está configurando el color de fondo en rojo cuando hace clic en un elemento en el ListView
.
Código final
MainActivity.java:
public class MainActivity extends ListActivity {
DBTools dbTools = new DBTools(this);
ArrayList<HashMap<String, String>> receiverList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().hide();
setContentView(R.layout.activity_main);
receiverList = dbTools.getAllReceivers();
dbTools.close();
ListView listView = getListView();
if(receiverList.size() != 0) {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int index, long id) {
view.setBackgroundColor(Color.RED);
TextView receiverIdTextView = (TextView) view.findViewById(R.id.receiverId);
selectionId = Integer.valueOf(receiverIdTextView.getText().toString());
((SimpleAdapter) getListAdapter()).notifyDataSetChanged();
}
});
SimpleAdapter adapter = new SimpleAdapter(MainActivity.this,receiverList, R.layout.receiver_entry, new String[] { "receiverId","receiverName", "fullPath"}, new int[] {R.id.receiverId, R.id.receiverName, R.id.fullPath}) {
@Override
public View getView (int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView receiverIdTextView = (TextView) view.findViewById(R.id.receiverId);
if(receiverIdTextView.getText().toString().equals(String.valueOf(selectionId))) {
view.setBackgroundColor(Color.RED);
} else {
view.setBackgroundColor(Color.WHITE);
}
return view;
}
};
setListAdapter(adapter);
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/black" >
<TextView
android:id="@+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="My List" />
</TableRow>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:id="@android:id/list" />
</TableLayout>
receiver_entry.xml
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/tableRow" >
<TextView
android:id="@+id/receiverId"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
<TextView
android:id="@+id/receiverName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Robotronics" />
<TextView
android:id="@+id/fullPath"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="123.45.678.910:8088/robtrox/find" />
</TableRow>
Problema
Estoy tratando de crear un ListView
con elementos seleccionables. Quiero poder hacer clic en un elemento en ListView
y hacer que el elemento cambie de color en la lista, y luego seguir y hacer otra cosa con los datos de la fila.
Estoy usando un SimpleAdapter
.
¿Cómo lo hago para que cuando toco una fila, cambie de color y, luego, cuando toco una fila diferente, la nueva fila se seleccione y cambie a un nuevo color, y la fila anterior vuelva a ser normal? ?
Código
Aquí está mi código hasta ahora. La clase DBTools
tiene todos los datos que deseo que se muestren en mi ListView
organizado y atendido. El método getAllReceivers()
devuelve una ArrayList
de HashMap<String, String>
s que tienen todos mis datos.
MainActivity.java:
public class MainActivity extends ListActivity {
DBTools dbTools = new DBTools(this);
ArrayList<HashMap<String, String>> receiverList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().hide();
setContentView(R.layout.activity_main);
receiverList = dbTools.getAllReceivers();
dbTools.close();
ListView listView = getListView();
if(receiverList.size() != 0) {
SimpleAdapter adapter = new SimpleAdapter(MainActivity.this,receiverList, R.layout.receiver_entry, new String[] {"receiverId","receiverName", "fullPath"}, new int[] {R.id.receiverId, R.id.receiverName, R.id.fullPath});
setListAdapter(adapter);
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/black" >
<TextView
android:id="@+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="My List" />
</TableRow>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:id="@android:id/list" />
</TableLayout>
receiver_entry.xml
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/tableRow" >
<TextView
android:id="@+id/receiverId"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
<TextView
android:id="@+id/receiverName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Robotronics" />
<TextView
android:id="@+id/fullPath"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="123.45.678.910:8088/robtrox/find" />
</TableRow>