¿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:

 <?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 el dispositivo (incorrecto)

Diseño distribuido en Eclipse (correcto):

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> 

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" /> 
  • Dependencia múltiple en checkboxpreference dependencia de android o listpreference
  • ¿Cómo se cambia el color de texto de los elementos de la lista en un AlertDialog
  • ¿Cómo abrir o simular clic en android ListPreference, que es dentro de la categoría de preferencia?
  • Multi seleccionar ListPreference en android
  • ¿Cómo se selecciona la opción de ListPreference?
  • ¿Hay una manera de mantener los divisores alrededor de una preferencia no seleccionable?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.