android listview radio-button listviewitem

Android ListView con RadioButton/CheckBox en el modo singleChoice y un diseño de fila personalizado



radio-button listviewitem (2)

Tengo un ListView, que está en modo singleChoice. Todo lo que quiero es mostrar un RadioButton al costado, que al hacer clic en los resaltados para decir que está seleccionado, y cuando se hace clic en uno diferente, uno se oculta y el nuevo se selecciona.

Busqué en el libro de Mark, Capítulo 8, "Getting Fancy With Lists" y su ejemplo de RateList
Pero no resuelve mi problema. Por favor, ayúdame .


Utilicé la respuesta de dbm y funcionó bien para mí, excepto una cosa:

Debe iniciar CheckedTextView en el método onAttachedToWindow() , no en onFinishInflate(). Esto se debe a que onAttachedToWindow() llamado onFinishInflate() y al usar la solución anterior, nunca verá ningún CheckedTextView en CheckedTextView -it es nulo cuando se onAttachedToWindow() .


EDITAR

Vale la pena mencionar que tenía un diseño personalizado en los elementos de mi lista: hay un icono, un título, una descripción y luego la casilla de verificación o el botón de opción (dependiendo de si se trata de una lista de opción única o múltiple). Mi solución de ejemplo es, por lo tanto, descrita por no menos de tres partes diferentes:

  1. El elemento de lista personalizado
  2. El dulce amor tierno: la implementación CheckableLinearLayout
  3. Un ejemplo de configuración ListView

  4. Y una bonificación:

  5. Ejemplo de implementación de Adapter::getView() .

Entonces vayamos a la magia, ¿o sí?

listitem.xml

<com.dbm.CheckableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:layout_width="32dp" android:layout_height="32dp" android:id="@+id/myIcon" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="@android:style/TextAppearance.Medium" android:textStyle="bold" android:ellipsize="end" android:id="@+id/myTitle" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="@android:style/TextAppearance.Small" android:textStyle="italic" android:ellipsize="end" android:id="@+id/myDescr" /> </LinearLayout> <CheckedTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@android:id/text1" /> </com.dbm.CheckableLinearLayout>

CheckableLinearLayout.java

public class CheckableLinearLayout extends LinearLayout implements Checkable { private CheckedTextView mCheckedTextView; private final Drawable mCheckDrawable; private final Drawable mRadioDrawable; private boolean mIsChecked; /** * Constructor. * * @param context The context to operate in. * @param attrs The attributes defined in XML for this element. */ public CheckableLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); TypedArray typedArray = null; // Cache the check box drawable. typedArray = context.getTheme().obtainStyledAttributes(new int[] {android.R.attr.listChoiceIndicatorMultiple}); if ((typedArray != null) && (typedArray.length() > 0)) { mCheckDrawable = typedArray.getDrawable(0); } else { // Fallback if the target theme doesn''t define a check box drawable. // Perhaps an application specific drawable should be used instead of null. mCheckDrawable = null; } // Careful with resources like this, we don''t need any memory leaks. typedArray.recycle(); // Cache the radio button drawable. typedArray = context.getTheme().obtainStyledAttributes(new int[] {android.R.attr.listChoiceIndicatorSingle}); if ((typedArray != null) && (typedArray.length() > 0)) { mRadioDrawable = typedArray.getDrawable(0); } else { // Fallback if the target theme doesn''t define a radio button drawable. // Perhaps an application specific drawable should be used instead of null mRadioDrawable = null; } // Careful with resources like this, we don''t need any memory leaks. typedArray.recycle(); mIsChecked = false; } /* * (non-Javadoc) * @see android.widget.Checkable#isChecked() */ public boolean isChecked() { return mIsChecked; } /* * (non-Javadoc) * @see android.view.View#onAttachedToWindow() */ @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); // Check if there is a valid GUI element that can visualize the current check-state. if (mCheckedTextView != null) { ViewParent p = getParent(); // Check if the parent of this list item is a ListView if (p instanceof ListView) { int choiceMode = ((ListView) p).getChoiceMode(); // Decide which check-state notation to visualize (check box, radio button or none). switch (choiceMode) { case ListView.CHOICE_MODE_MULTIPLE: mCheckedTextView.setCheckMarkDrawable(mCheckDrawable); break; case ListView.CHOICE_MODE_SINGLE: mCheckedTextView.setCheckMarkDrawable(mRadioDrawable); break; default: mCheckedTextView.setCheckMarkDrawable(null); break; } } } } /* * (non-Javadoc) * @see android.view.View#onFinishInflate() */ @Override protected void onFinishInflate() { super.onFinishInflate(); mCheckedTextView = (CheckedTextView) findViewById(android.R.id.text1); } /* * (non-Javadoc) * @see android.widget.Checkable#setChecked(boolean) */ public void setChecked(boolean checked) { mIsChecked = checked; if (mCheckedTextView != null) { mCheckedTextView.setChecked(mIsChecked); } } /* * (non-Javadoc) * @see android.widget.Checkable#toggle() */ public void toggle() { setChecked(!mIsChecked); } }

exampleListView.xml

¡NOTA! que automáticamente obtendrá casillas de verificación si establece el atributo android:choiceMode en "multipleChoice" y botones de "singleChoice" si lo establece en "singleChoice" , siempre que utilice la implementación anterior.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:choiceMode="singleChoice" android:id="@+id/myList" /> </LinearLayout>

Bonificación: MyCustomAdapter :: getView ()

Este se basa en un Cursor. Por supuesto, lo implementará como mejor le parezca.

private final class ViewHolder { public ImageView iconView; public TextView titleView; public TextView descriptionView; } /* * (non-Javadoc) * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup) */ public View getView(int position, View convertView, ViewGroup parent) { View view = null; // Only do something if the requested position exists within the Cursor. if (mCursor.moveToPosition(position)) { ViewHolder viewHolder; view = convertView; if (view == null) { // Create and initialize a new view if not created already for this position. view = mLayoutInflater.inflate(R.layout.listitem, null); // Don''t "find view by id" each and every time, but rather save a reference // to them and associate the references with the list item itself by storing // them in the list items "tag" attribute. When the view is re-used later on, // you already have a reference to its views and don''t need to find them // again, which is a time-consuming operation. viewHolder = new ViewHolder(); viewHolder.iconView = (ImageView) view.findViewById(R.id.myIcon); viewHolder.titleView = (TextView) view.findViewById(R.id.myTitle); viewHolder.descriptionView = (TextView) view.findViewById(R.id.myDescr); view.setTag(viewHolder); } else { // Get the references to the views for this, already existing list item. viewHolder = (ViewHolder) view.getTag(); } // Create a bitmap from the byte array in the database. byte[] buffer = mCursor.getBlob(mIconColumnIndex); Bitmap icon = null; // Try to decode the byte array if it exists. if (buffer != null) { icon = BitmapFactory.decodeByteArray(buffer, 0, buffer.length); } // Update the views with new data. viewHolder.iconView.setImageBitmap(icon); String title = mCursor.getString(mTitleColumnIndex); viewHolder.titleView.setText(title); String description = mCursor.getString(mDescriptionColumnIndex); viewHolder.descriptionView.setText(description); } // Return a view showing the correct data for the item at ''position''. return view; }

RESPUESTA ORIGINAL:

Puedo sugerir este enlace:

http://tokudu.com/2010/android-checkable-linear-layout/

Yo mismo he tenido un gran placer cuando estaba en su posición exacta :-) Si todavía hay algo que no está claro, no dude en especificar su pregunta y con mucho gusto intentaré ayudarlo o ayudarlo con más ejemplos de código (tal como lo mencioné anteriormente: Estuve en tu posición hace solo unos días).