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.
Me pareció muy útil este pequeño código: http://alvinalexander.com/java/jwarehouse/apps-for-android/RingsExtended/src/com/example/android/rings_extended/CheckableRelativeLayout.java.shtml
Es una gran adición al contenido http://www.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/ @ ferdy182.
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.
Tienes que hacer tu propio RelativeLayout
que implemente la interfaz de Checkable
y tener una referencia a CheckBox
o CheckedTextView
(o una lista si es el modo de elección múltiple).
Mira esta publicación: http://www.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/