studio programacion herramientas fundamentos con avanzado aplicaciones android listview user-interface custom-view

android - programacion - ¿Lista de opciones múltiples con vista personalizada?



manual de android en pdf (9)

Cada vista tiene un TextView y un CheckBox.

No, no es así. Tiene un CheckedTextView .

Entonces, ¿qué debo hacer para hacer una lista de opciones múltiples con mi vista personalizada para cada fila?

Intente hacer que CheckBox android:id sea "@android:id/text1" y vea si eso ayuda. Esa es la identificación que usa Android para CheckedTextView en simple_list_item_multiple_choice .

He visto el ejemplo com.example.android.apis.view.List11 de ApiDemos. En ese ejemplo, cada fila toma la vista android.R.simple_list_item_multiple_choice . Cada vista tiene un TextView y un CheckBox .

Ahora quiero que cada vista tenga 2 TextView y 1 CheckBox , algo similar al ejemplo de List3 . Intenté crear un archivo de diseño personalizado row.xml como este:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <CheckBox android:id="@+id/checkbox" android:layout_alignParentRight="true" android:layout_width="wrap_content" android:layout_height="fill_parent" /> <TextView android:id="@+id/text_name" android:textSize="13px" android:textStyle="bold" android:layout_toLeftOf="@id/checkbox" android:layout_alignParentLeft="true" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/text_phone" android:textSize="9px" android:layout_toLeftOf="@id/checkbox" android:layout_below="@id/text_name" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </RelativeLayout>

Luego en Activity onCreate() , me gusta esto:

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Query the contacts mCursor = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null); startManagingCursor(mCursor); ListAdapter adapter = new SimpleCursorAdapter(this, R.layout.row, mCursor, new String[] { Phones.NAME, Phones.NUMBER}, new int[] { R.id.text_name, R.id.text_phone }); setListAdapter(adapter); getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); }

El resultado se parece a lo que quiero, pero parece que la lista no sabe qué elemento está seleccionado. Además, necesito hacer clic exactamente en el CheckBox . En el ejemplo de List11, solo necesito hacer clic en la fila del elemento.

Entonces, ¿qué debo hacer para hacer una lista de opciones múltiples con mi vista personalizada para cada fila? Muchas gracias.


Ejemplo simple de cómo hacer que un diseño personalizado funcione como una casilla de verificación personalizada:

private class FriendsAdapter extends ArrayAdapter<WordsterUser> { private Context context; public FriendsAdapter(Context context) { super(context, R.layout.listitem_oneline); this.context = context; } @Override public View getView(int position, View convertView, ViewGroup parent) { final int pos = position; LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View rv = inflater.inflate(R.layout.listitem_oneline, parent, false); rv.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { boolean checked = friendsListView.isItemChecked(pos); friendsListView.setItemChecked(pos, !checked); } }); WordsterUser u = getItem(position); TextView itw = (TextView) rv.findViewById(R.id.ItemTextView); itw.setText(u.userName + " (" + u.loginName + ")"); ImageView iv = (ImageView) rv.findViewById(R.id.SelectButton); if (friendsListView.isItemChecked(position)) { iv.setImageResource(R.drawable.downbutton); } else { iv.setImageResource(R.drawable.upbutton); } return rv; } }


Es posible por algún truco

en su método ListActivtyClass in

protected void onListItemClick(ListView l, View v, int position, long id) { //just set <your_model>.setSelected(true); }

ahora en tu Adaptador personalizado

public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(textViewResourceId, parent, false); } if (<your_model>.isSelected()) { convertView.setBackgroundColor(Color.BLUE); } else { convertView.setBackgroundColor(Color.BLACK); } return convertView; }

De esta forma, puede personalizar la vista en el adaptador cuando el elemento está seleccionado en la lista.


La respuesta de Rahul Garg es buena por primera vez que se carga la lista, si desea que se revisen algunas filas según los datos del modelo, pero después de eso debe manejar los eventos de verificación / desmarcación por su cuenta.

Puede anular el onListItemCLick() de ListActivity para marcar / desmarcar las filas

@Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); ViewGroup row = (ViewGroup)v; CheckBox check = (CheckBox) row.findViewById(R.id.checkbox); check.toggle(); }

Si lo hace, no configure ListView como CHOICE_MODE_MULTIPLE , porque CHOICE_MODE_MULTIPLE cosas extrañas al llamar a la función.

Para recuperar la lista de filas marcadas, debe implementar un método usted mismo, llamando a getCheckItemIds() en el ListView no funciona:

ListView l = getListView(); int count = l.getCount(); for(int i=0; i<count; ++i) { ViewGroup row = (ViewGroup)l.getChildAt(i); CheckBox check = (Checked) row.findViewById(R.id.ck1); if( check.isChecked() ) { // do something } }


La solución es crear una vista personalizada que implemente la interfaz Clickable.

public class OneLineCheckableListItem extends LinearLayout implements Checkable { public OneLineCheckableListItem(Context context, AttributeSet attrs) { super(context, attrs); } private boolean checked; @Override public boolean isChecked() { return checked; } @Override public void setChecked(boolean checked) { this.checked = checked; ImageView iv = (ImageView) findViewById(R.id.SelectImageView); iv.setImageResource(checked ? R.drawable.button_up : R.drawable.button_down); } @Override public void toggle() { this.checked = !this.checked; } }

Y cree un diseño personalizado para los elementos de la lista usando el nuevo widget.

<?xml version="1.0" encoding="utf-8"?> <ax.wordster.OneLineCheckableListItem xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="4dp" android:background="@drawable/selector_listitem" android:orientation="horizontal" > <ImageView android:id="@+id/SelectImageView" android:layout_width="60dp" android:layout_height="60dp" android:src="@drawable/button_friends_down" /> <TextView android:id="@+id/ItemTextView" android:layout_width="fill_parent" android:layout_height="60dp" android:gravity="center" android:text="@string/___" android:textAppearance="?android:attr/textAppearanceLarge" android:textColor="@color/text_item" /> </ax.wordster.OneLineCheckableListItem>

A continuación, cree un nuevo Adaptador personalizado utilizando el diseño anterior.



Obtuve la solución ... Puede obtener los clics en las vistas (como casillas de verificación en diseños personalizados de la fila) agregando oyente a cada uno de ellos en el adaptador mismo mientras devuelve la vista convertida en getView (). Posiblemente deba pasar una referencia de objeto de lista si intenta obtener información específica de la lista. como la identificación de la fila.


Quiero confirmar que la respuesta del Pritam es correcta. Necesita un onClickListener en cada elemento de la lista ( getView() en getView() del adaptador).

Puede crear un nuevo onClickListener() para cada elemento, o hacer que el adaptador implemente onClickListener() ; en este caso, los elementos deben etiquetarse para que el oyente sepa, en qué elemento está operando.

Confiar en la lista onItemClickListener() , como alguien aconsejó en otro hilo, no funcionará, ya que el CheckBox interceptará el evento click para que la lista no lo obtenga.

Y finalmente @Rahul y JVitella:

La situación es que el CheckBox en un elemento de la lista debe poder hacer clic y controlarse independientemente del elemento de la lista. Por lo tanto, la solución es como acabo de describir arriba.