How to Limit the Height of Spinner Drop Down View in Android

How to limit the height of Spinner drop down view in Android

You can use Reflection.

    Spinner spinner = (Spinner) findViewById(R.id.spinner);
try {
Field popup = Spinner.class.getDeclaredField("mPopup");
popup.setAccessible(true);

// Get private mPopup member variable and try cast to ListPopupWindow
android.widget.ListPopupWindow popupWindow = (android.widget.ListPopupWindow) popup.get(spinner);

// Set popupWindow height to 500px
popupWindow.setHeight(500);
}
catch (NoClassDefFoundError | ClassCastException | NoSuchFieldException | IllegalAccessException e) {
// silently fail...
}

How do I set the maximum length for a spinner's drop-down list?

One way to achieve this is to use ActionBarSherlock's IcsSpinner. I made the needed modifications to limit the size of the spinner and that seems to work nicely.

Make the following modifications to IcsListPopupWindow.

Add an instance variable:

private int mDropDownVerticalOffsetBottom;

Add a method to set this variable:

public void setVerticalOffsetBottom(int offsetBottom) {
mDropDownVerticalOffsetBottom = offsetBottom;
}

Alter the call to getMaxAvailableHeight to (mDropDownVerticalOffsetBottom was added):

final int maxHeight = /*mPopup.*/getMaxAvailableHeight(
mDropDownAnchorView, mDropDownVerticalOffset, mDropDownVerticalOffsetBottom, ignoreBottomDecorations);

Change the method's signature to include that variable:

private int getMaxAvailableHeight(View anchor, int yOffset, int yOffsetBottom, boolean ignoreBottomDecorations) {

And consider that offset when computing the distance to the bottom:

final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset - yOffsetBottom;

Now modify IcsSpinner.java to implement the setter method for the offset:

private DropdownPopup mPopup;   // <- needs to be a DropdownPopup instead of a SpinnerPopup

public void setVerticalOffsetBottom(int offsetBottom) {
mPopup.setVerticalOffsetBottom(offsetBottom);
}

Now "all" you need to do is to set the offset to the correct value. Here's how I did it (I tested it and it worked on two test devices):

final View root = findViewById(R.id.root_layout);
final View view = findViewById(R.id.view_not_to_be_obscured);
root.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
root.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int[] locations = new int[2];
root.getLocationOnScreen(locations);
int y1 = locations[1];
int h1 = root.getHeight();
view.getLocationOnScreen(locations);
int y2 = locations[1];
int offset = y1 + h1 - y2;
// here we initialize the spinner
}
});

The assumption is that root_layout fills the whole window excluding all decorating elements.

The final step is to create the spinner itself:

    // actionDropDownStyle is an attribute set in the theme to e.g. @style/Widget.Sherlock.Spinner.DropDown.ActionBar or @style/Widget.Sherlock.Light.Spinner.DropDown.ActionBar for light theme
IcsSpinner spinner = new IcsSpinner(context, null, R.attr.actionDropDownStyle);

// yes here we set the offset!
spinner.setVerticalOffsetBottom(offset);

spinner.setPadding(spinner.getPaddingLeft(), 0, spinner.getPaddingRight(), 0);
spinner.setId(R.id.some_id);
spinner.setAdapter(yourAdapter); // you can use a simple ArrayAdapter or whatever you need

// create ICS LinearLayout
LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
IcsLinearLayout linearLayout = (IcsLinearLayout) inflater.inflate(R.layout.abs__action_bar_tab_bar_view, null);
linearLayout .setPadding(listNavLayout.getPaddingLeft(), 0, listNavLayout.getPaddingRight(), 0);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
params.gravity = Gravity.CENTER;
linearLayout .addView(spinner, params);

Now that might look complicated but as someone else mentioned, you'll not be able to achieve this without your own spinner implementation and since ActionBarSherlock comes with one, why not use it? It's certainly less work than writing your own one. If you don't use the library for the ActionBar strip away all resource files you don't need and use Proguard to strip away all unused classes.
You could probably achieve the same using AppCompat (see here: https://github.com/android/platform_frameworks_support/tree/master/v7/appcompat/src/android/support).

Android limit the spinner popup height

Ok, the only solution that works for me is to use third party MaterialSpinner library. Maybe it will be useful also for others as there is no native way to change the dropdown height.

Just to implement: implementation 'com.jaredrummler:material-spinner:1.3.1'

The spinner.xml:

 <com.jaredrummler.materialspinner.MaterialSpinner
android:id="@+id/spinner1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:ms_dropdown_max_height="200dp"
android:dropDownSelector="@color/colorAccent"
android:popupBackground="@drawable/custombg"
style="@style/Myspinner"
android:layout_margin="5dp"
android:gravity="center_vertical"
android:spinnerMode="dropdown"/>

Java code:

 final MaterialSpinner sp1 = (MaterialSpinner) findViewById(R.id.spinner1);

String[] arrayItems = myList.categories;

ArrayAdapter<String> adp1 = new ArrayAdapter<>(this, R.layout.spinner_item, arrayItems);
adp1.setDropDownViewResource(R.layout.my_spinnerlist);
sp1.setAdapter(adp1);

sp1.setSelected(false);

sp1.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener() {
@Override
public void onItemSelected(MaterialSpinner view, int position, long id, Object item) {

}
} );

Works like a charm, see the app:ms_dropdown_max_height="200dp" in XML file.

Modify the Size of an Android Spinner Drop down part Size?

You can not change the size of spinner as it is default widget. But you can make it custom using background image. Here is my code:

<Spinner 
android:id="@+id/spinner"
android:layout_width="fill_parent"
android:layout_height="45dp"
android:drawSelectorOnTop = "true"
android:layout_marginLeft="20dp"
android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_below="@+id/placeCity"
android:paddingLeft="5dip"
android:background="@drawable/myspinner_background"
/>
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/spinner"
android:layout_alignTop="@+id/spinner"
android:layout_marginRight="5dp"
android:layout_marginTop="10dp"
android:src="@drawable/down" />

This is written in XML. And make another file called myspinner_background.xml in drawable folder. Inside that, write this code:

<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<stroke
android:color="#f269be"
android:width="2dp" />
<solid
android:color="#ECC8EC" />



Related Topics



Leave a reply



Submit