6

I have some spinners on the layout and use loader to load their data from db in background. The problems is that empty spinners have smaller height until the data are loaded. So the layout jump.

How can I prevent this jumping?

Edit (added spinner row layouts)

Spinner row:

<?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/Text1"
        style="@style/StyleSpinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

Spinner drop down row:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="@dimen/style_spinner_row_padding" >

    <TextView
        android:id="@+id/Text1"
        style="@style/StyleSpinnerDropDownRow1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" />

    <TextView
        android:id="@+id/Text2"
        style="@style/StyleSpinnerDropDownRow2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/Text1" />

</RelativeLayout>

Assigned styles:

<!-- // Spinner // -->
<style name="StyleSpinner" parent="AppTheme">
    <item name="android:textStyle">bold</item>
    <item name="android:gravity">start</item>
    <item name="android:textSize">@dimen/default_text_size_normal</item>
    <item name="android:padding">@dimen/style_spinner_row_padding</item>
</style>

<style name="StyleSpinnerDropDownRow1" parent="AppTheme">
    <item name="android:textStyle">bold</item>
    <item name="android:textSize">@dimen/default_text_size_normal</item>
</style>

<style name="StyleSpinnerDropDownRow2" parent="AppTheme">
    <item name="android:textStyle">normal</item>
    <item name="android:textSize">@dimen/default_text_size_small</item>
</style>

Screen shots:

enter image description here enter image description here

WebDucer
  • 1,114
  • 2
  • 16
  • 39
  • You can use an image which looks like drop down and set it as background of every spinner. Please let me know if that works. If possible then please go through the link http://www.mkyong.com/android/android-spinner-drop-down-list-example/ and place an empty spinner there. You can see no fluctuation of height is occurring there. – sUndeep Feb 02 '14 at 17:15
  • I use the standard way of spinners (like in the tuturial) but with cursor (database data). And I use two own layout for spinner and drop down (I added the XML to the description). – WebDucer Feb 02 '14 at 18:11

3 Answers3

4

I've just had this same issue and managed to fix it for myself so here's what I did.

I am inflating android.R.layout.simple_spinner_dropdown_item in my spinner adapter for each item layout. When I looked at this layout I noticed it had no margins but just a set height which was coming from android:attr/dropdownListPreferredItemHeight.

So I thought I'd get this list preferred item height value programatically and set it as my spinners minimum height. Using the answer to this stackoverflow question I was able to get the correct value and set it to my spinner.

    android.util.TypedValue value = new android.util.TypedValue();
    getActivity().getTheme().resolveAttribute(android.R.attr.listPreferredItemHeight, value, true);
    android.util.DisplayMetrics metrics = new android.util.DisplayMetrics();
    getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
    float ret = value.getDimension(metrics);

    mSpinner.setMinimumHeight((int) (ret - 1 * metrics.density));

I've removed 1dip because it seems that the returned value has been rounded up which makes it 1 pixel too high.

Now all my spinner are the same height, whether they have items or are empty.

Community
  • 1
  • 1
Steven Trigg
  • 1,903
  • 2
  • 19
  • 22
  • This works perfectly and build the basis for my own minHeight calculation. I reduce the spinner height for small screen sizes. `float reduce = context.getResources().getDimension(R.dimen.style_spinner_reduced_height); float ret = value.getDimension(metrics); spinner.setMinimumHeight((int) (ret - reduce - 1 * metrics.density));` The default value for reduce is 12dp for me. – WebDucer Mar 02 '14 at 11:37
  • 1
    Tried this, but the minimum height seems to be a lot bigger than the height when this code was not applied and the spinner was filled with real items. – Damn Vegetables Jan 08 '16 at 04:14
  • to anyone who wants to use this on xml can use like this android:layout_height="?attr/dropdownListPreferredItemHeight" – Hüseyin Bülbül Apr 10 '19 at 13:16
1

To prevent the heights changing from when I load it in the background I just created a none array and in the xml set the entries to it:

In array.xml

 <string-array name="none">
        <item></item>
 </string-array>

In the spinners

android:entries:@array/none

The heights do not change because once the loader finishes it replaces the contents of the spinner anyway.

jbejar
  • 131
  • 7
-1

I used an arrayAdapter<String> with an empty array.

After you have got what you need just get a new adapter or use the same adapter and call notifyDataSetChanged().

skuntsel
  • 11,624
  • 11
  • 44
  • 67