Why does the ListView stay above the TextView in the ListPreference dialog box?

I need to create a custom ListPreference dialog to add a title text (TextView) above the list (ListView). I created a class MyListPreference that extends ListPreference and overrides 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; } 

My xml layout dialog_preference_list.xml contains:

 <?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> 

Problem: TextView appears below ListView, not above. I need the TextView to be taller. I tried both with LinearLayout and RelativeLayout (using the attributes "below" or "above") without success: I cannot find a way to place the TextView over the ListView ... The layout is pretty simple and I can not see why the list remains above ... Also draw attention that the problem occurs both on a real device (Nexus 4, Android 4.2.2), and on the emulator. However, when viewing the layout presented in the Eclipse graphic layout, the layout is correct! See both attached images.

Any idea on how to solve this problem?

Layout displayed on the device (incorrect):

Layout rendered on the device (incorrect)

Layout made on Eclipse (correct):

Layout rendered on Eclipse (correct)

Change using solution 10.07.2013

As suggested by the accepted answer, the problem is due to using builder.setSingleChoiceItems () in ListPreference onPrepareDialogBuilder (). I fixed this by expanding ListPreference and overriding onCreateDialogView () to build a dialog without a builder so that I can create a custom view that displays the title text above the list items.

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> 
+7
source share
4 answers

I think the problem is how ListPreference works. ListPreference uses Builder.setSingleChoiceItems () to create rows using RadioButtons and has preference over the custom layout you are trying to add (in your case, TextView and ListView inside LinearLayout). Instead, the solution extends DialogPreference. Here 's a link to GitHub where I created a custom DialogPreference dialog that does what you need. I have not coded the logic of RadioButton.

+4
source

I guess this is a topic. Try changing the theme of your dialogue inside the constructor, do something like setStyle(STYLE_NO_TITLE, R.style.AppTheme) . The theme of your base application is of type no_title.

If this is not a problem, this may be due to the ListPreference class ListPreference . This could be overriding your layout for consistency when viewing preference views. However, I have not used ListPreference , so this is just an assumption.

Can you reproduce the same result by playing with themes in an XML graphic layout view?

+2
source

Another option you can try is to add a TextView as a title to the ListView as follows:

 TextView textView = new TextView(getActivity()); ListView listView = new ListView(getActivity()); listView.addHeaderView(textView); 

addHeaderView accepts a View , so you theoretically have everything you want to be a title, but I used only a TextView .

+1
source

The above link does not work. In this solution, the idea overrides ListPreference and inflates your own list, with the data defined in 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; } 

Another important thing is to call onPrepareDialogBuilder and not call super. This will prevent the list from appearing twice.

 @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()); } 

Where dialog_preference_list_header in my case is only a TestView, but it can be a more complicated view, and custom_dialog_single_choice_list_adapter can be something like this:

 <?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" /> 
0
source

All Articles