Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't make spinner's scrollbar always visible (Android)

I have such a problem - I want to make spinner's scrollbar always visible. But for spinner function

setScrollbarFadingEnabled(false);

causes crash with a NullExceptionPointer during drawing the GUI.

XML tags can't solve this problem too - it seems that spinner just ignore them.

Maybe there are another ways to move? For example, using of the custom scrollbar? If yes, how can I do this?

Thanks for your answers, Dmitry.

As I've been asked, here is LogCat error message for simple project with just a spinner in it:

AndroidRuntime(2252): FATAL EXCEPTION: main
AndroidRuntime(2252): java.lang.NullPointerException
AndroidRuntime(2252): at android.view.View.onDrawScrollBars(View.java:5836)
AndroidRuntime(2252): at android.view.View.draw(View.java:6799)
AndroidRuntime(2252): at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
AndroidRuntime(2252): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
AndroidRuntime(2252): at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
AndroidRuntime(2252): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
AndroidRuntime(2252): at android.view.View.draw(View.java:6796)
AndroidRuntime(2252): at android.widget.FrameLayout.draw(FrameLayout.java:352)
AndroidRuntime(2252): at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
AndroidRuntime(2252): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
AndroidRuntime(2252): at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
AndroidRuntime(2252): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
AndroidRuntime(2252): at android.view.View.draw(View.java:6796)
AndroidRuntime(2252): at android.widget.FrameLayout.draw(FrameLayout.java:352)
AndroidRuntime(2252): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2078)
AndroidRuntime(2252): at android.view.ViewRoot.draw(ViewRoot.java:1433)
AndroidRuntime(2252): at android.view.ViewRoot.performTraversals(ViewRoot.java:1175)
AndroidRuntime(2252): at android.view.ViewRoot.handleMessage(ViewRoot.java:1753)
AndroidRuntime(2252): at android.os.Handler.dispatchMessage(Handler.java:99)
AndroidRuntime(2252): at android.os.Looper.loop(Looper.java:123)
AndroidRuntime(2252): at android.app.ActivityThread.main(ActivityThread.java:4632)
AndroidRuntime(2252): at java.lang.reflect.Method.invokeNative(Native Method)
AndroidRuntime(2252): at java.lang.reflect.Method.invoke(Method.java:521)
AndroidRuntime(2252): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871)
AndroidRuntime(2252): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
AndroidRuntime(2252): at dalvik.system.NativeStart.main(Native Method)
like image 428
Dmitry Avatar asked Apr 04 '12 15:04

Dmitry


People also ask

Which of the following look like a dropdownlist in android?

Spinner is a widget similar to a drop-down list for selecting items. In this tutorial, we show you how to do the following tasks : Render a Spinner in XML, and load the selection items via XML file also. Render another Spinner in XML, and load the selection items via code dynamically.

Whats a scroll view?

In Android, a ScrollView is a view group that is used to make vertically scrollable views. A scroll view contains a single direct child only. In order to place multiple views in the scroll view, one needs to make a view group(like LinearLayout) as a direct child and then we can define many views inside it.

What is spinner in android with example?

Spinners provide a quick way to select one value from a set. In the default state, a spinner shows its currently selected value. Touching the spinner displays a dropdown menu with all other available values, from which the user can select a new one.


2 Answers

Spinner does not have a scrollbar, Hence you are getting NullPointerException.

The popup shown by spinner has a scrollbar. So you need to change the properties of the ListView shown by spinner. But ListView itself is not exposed by Spinner by any public methods.

Even if you get the ListPopupWindow by reflection, a further problem arises, that ListPopupWindow's ListView is only created after you click the Spinner.

But OnClickListener of the Spinner cannot be registered , to set the ListView Properties after the show.

You could create a Custom Spinner with performClick overridden and then get mPopup by reflection. and use mPopup.getListView().setScrollbarFadingEnabled(false)

But If you are going to create a custom Spinner, i believe it is easier to implement the whole popup to suit your needs than using reflection.

like image 126
nandeesh Avatar answered Nov 03 '22 00:11

nandeesh


Thank @nandeesh for his/her answer and also @Eng.Fouad for his/her answer on another page.

public class VisibleScrollbarSpinner extends Spinner {
    @Override public boolean performClick() {
        final boolean superResult = super.performClick();

        try {
            final Field mPopupField = Spinner.class.getDeclaredField("mPopup");
            mPopupField.setAccessible(true);
            //noinspection ConstantConditions
            ((ListPopupWindow) mPopupField.get(this)).getListView().setScrollbarFadingEnabled(false);
            mPopupField.setAccessible(false);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            Log.e(TAG, e.toString(), e);
        }

        return superResult;
    }

    public VisibleScrollbarSpinner(Context context) { super(context); } 
    public VisibleScrollbarSpinner(Context context, int mode) { super(context, mode); } 
    public VisibleScrollbarSpinner(Context context, AttributeSet attrs) { super(context, attrs); } 
    public VisibleScrollbarSpinner(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } 
    public VisibleScrollbarSpinner(Context context, AttributeSet attrs, int defStyleAttr, int mode) { super(context, attrs, defStyleAttr, mode); }
}
like image 34
Mir-Ismaili Avatar answered Nov 03 '22 01:11

Mir-Ismaili