¿Por qué ListView se mantiene por encima de TextView en el cuadro de diálogo ListPreference?
Necesito crear un cuadro de diálogo ListPreference personalizado para que pueda agregar algún texto de encabezado (un TextView) por encima de la Lista (ListView). He creado la clase MyListPreference que extiende ListPreference y sobreescribe onCreateDialogView ():
@Override protected View onCreateDialogView() { LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); View v = (View) inflater.inflate(R.layout.dialog_preference_list, null); return v; }
Mi diseño XML dialog_preference_list.xml contiene:
- Cómo setOnTouchListener () en un ListPreference?
- Fila personalizada en una listaPreferencia?
- Cómo establecer el valor predeterminado de un ListPreference
- Cómo vincular el archivo de preferencias automáticas a las preferencias personalizadas en android
- Cómo personalizar el botón de opción de preferencia de lista
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" /> <ListView android:id="@android:id/list" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawSelectorOnTop="false" android:scrollbarAlwaysDrawVerticalTrack="true" /> </LinearLayout>
Problema: El TextView se muestra debajo de ListView en lugar de arriba. Necesito que el TextView esté arriba. He intentado ambos con LinearLayout y RelativeLayout (usando atributos "below" o "above") sin éxito: No puedo encontrar una manera de poner el TextView encima de ListView … El diseño es bastante simple y no puedo ver Por qué la lista permanece por encima de … También, tenga en cuenta que el problema se produce tanto en un dispositivo real (Nexus 4, Android 4.2.2) y el emulador. Sin embargo, al mirar la disposición rendida en la disposición gráfica de Eclipse, la disposición es correcta! Vea las dos imágenes adjuntas.
¿Alguna idea de cómo resolver esto?
Diseño distribuido en el dispositivo (incorrecto):
Diseño distribuido en Eclipse (correcto):
Editar con la solución 10.07.2013
Como sugiere la respuesta aceptada, el problema proviene del uso de builder.setSingleChoiceItems () en onPrepareDialogBuilder () de ListPreference. Lo he arreglado extendiendo ListPreference y reemplazando onCreateDialogView () para crear el Diálogo sin el constructor para que pueda crear una Vista personalizada que muestre el texto del encabezado sobre los elementos de la lista.
GPListPreference.java:
public class GPListPreference extends ListPreference { ... @Override protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { builder.setNegativeButton(null, null); builder.setPositiveButton(null, null); } private int getValueIndex() { return findIndexOfValue(getValue()); } @Override protected View onCreateDialogView() { LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); ListView lv = (ListView) inflater.inflate(R.layout.dialog_preference_list, null); TextView header = (TextView) inflater.inflate(R.layout.dialog_preference_list_header, null); header.setText(getDialogMessage()); // you should set the header text as android:dialogMessage in the preference XML lv.addHeaderView(header); ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(getContext(), R.layout.dialog_preference_list_singlechoice, getEntries()); lv.setAdapter(adapter); lv.setClickable(true); lv.setEnabled(true); lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE); lv.setItemChecked(getValueIndex() + 1, true); lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { setValueIndex(position - 1); getDialog().dismiss(); } }); return lv; } }
Dialog_preference_list.xml:
<?xml version="1.0" encoding="utf-8"?> <ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/list" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawSelectorOnTop="false" android:scrollbarAlwaysDrawVerticalTrack="true" />
Dialog_preference_list_singlechoice.xml
<?xml version="1.0" encoding="utf-8"?> <CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" android:checkMark="?android:attr/listChoiceIndicatorSingle" android:ellipsize="marquee" android:gravity="center_vertical" android:minHeight="?android:attr/listPreferredItemHeight" android:paddingBottom="2dip" android:paddingLeft="10dip" android:paddingRight="10dip" android:paddingTop="2dip" android:textAppearance="?android:attr/textAppearanceMedium" />
Dialog_preference_list_header.xml
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dip" android:textAppearance="?android:attr/textAppearanceSmall"> </TextView>
- ¿Por qué preferences.getString ("key", "DEFAULT") devuelve siempre "DEFAULT"?
- ¿Cómo agregar efecto de rizado a las preferencias en android?
- Cómo agregar contentDescription a ListPreference?
- El valor por defecto de ListPreference no aparece
- ¿Cómo editar / restablecer Alarm Manager?
- Desplazarse a / establecer la posición de la preferencia de lista personalizada
- Color del texto de la fila de elementos de ListPreference
- ¿Cuál es la diferencia entre las entradas y los valores de entrada en android listPreferences xml?
Creo que el problema es con la forma en que funciona ListPreference. ListPreference utiliza Builder.setSingleChoiceItems () para crear las filas con los RadioButtons, y tiene preferencia sobre el diseño personalizado que está intentando agregar (en su caso un TextView y un ListView dentro de un LinearLayout.) La solución está extendiendo DialogPreference en su lugar. Un enlace a un GitHub donde he creado una DialogPreference personalizada que hace lo que necesitas.No he codificado la lógica RadioButton.
Supongo que es un tema temático. Intente cambiar el tema de su diálogo dentro del constructor que sea algo como setStyle(STYLE_NO_TITLE, R.style.AppTheme)
. Su tema de la aplicación base con estilo no_title.
Si este no es el problema que podría estar relacionado con la clase ListPreference
sí. Podría estar reemplazando su diseño por la consistencia en el tema de las vistas de preferencia. Sin embargo, no he utilizado ListPreference
antes, por lo que es sólo una suposición.
¿Puede reproducir el mismo resultado jugando con los temas en la vista previa de diseño gráfico XML?
Otra opción que puede intentar es agregar el TextView
como un encabezado al ListView
como este:
TextView textView = new TextView(getActivity()); ListView listView = new ListView(getActivity()); listView.addHeaderView(textView);
El addHeaderView
toma una View
para que teóricamente tenga algo que desea ser el encabezado, pero sólo he utilizado un TextView
.
El enlace de arriba está roto. En esta solución la idea es reemplazar ListPreference e inflar su propia lista con los datos definidos en ListPreference.
@Override protected View onCreateDialogView() { LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); ListView lv = new ListView(getContext()); // Inflate the view into the header only if a message was set if (getDialogMessage() != null && ! getDialogMessage().equals("") ) { TextView header = (TextView) inflater.inflate(R.layout.dialog_preference_list_header, null); header.setText(getDialogMessage()); lv.addHeaderView(header, null, false); } // Create a new adapter and a list view and feed it with the ListPreference entries ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(getContext(), R.layout.custom_dialog_single_choice_list_adapter, getEntries()); lv.setAdapter(adapter); lv.setClickable(true); lv.setEnabled(true); lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE); lv.setItemChecked(getValueIndex() + 1, true); lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { setValueIndex(position - 1); getDialog().dismiss(); } }); return lv; }
Otra cosa importante es llamar onPrepareDialogBuilder y no llamar super en él. Esto evitará que la vista de lista aparezca dos veces.
@Override protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { // Not calling super, to avoid having 2 listviews // Set the positive button as null builder.setPositiveButton(null, null); } private int getValueIndex() { return findIndexOfValue(getValue()); }
Donde dialog_preference_list_header es en mi caso sólo un TestView, pero podría ser una vista más compleja, y custom_dialog_single_choice_list_adapter podría ser algo como esto:
<?xml version="1.0" encoding="utf-8"?> <CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" android:checkMark="?android:attr/listChoiceIndicatorSingle" android:ellipsize="marquee" android:gravity="center_vertical" android:minHeight="?android:attr/listPreferredItemHeight" android:paddingBottom="2dip" android:paddingLeft="10dip" android:paddingRight="10dip" android:paddingTop="2dip" android:textAppearance="?android:attr/textAppearanceMedium" />
- Android cuadro de diálogo personalizado con scrollview empuja los botones de la pantalla
- Cómo borrar la pila del historial de actividades al pulsar el botón de inicio?