无法使微调器的滚动条始终可见(Android)

时间:2012-04-04 15:37:59

标签: android scrollbar spinner

我有这样的问题 - 我想让微调器的滚动条始终可见。 但对于微调器功能

setScrollbarFadingEnabled(false);
在绘制GUI时,

会导致NullExceptionPointer崩溃。

XML标签也无法解决这个问题 - 似乎spinner只是忽略它们。

也许还有其他方法可以移动?例如,使用自定义滚动条?如果是,我该怎么做?

感谢您的回答, 梅德。

正如我被问到的,这里有一个简单项目的LogCat错误信息,里面只有一个微调器:

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)

6 个答案:

答案 0 :(得分:7)

Spinner没有滚动条,因此你得到NullPointerException。

spinner显示的弹出窗口有一个滚动条。因此,您需要更改由微调器显示的ListView的属性。但是Spinner没有通过任何公共方法公开ListView本身。

即使您通过反射获得ListPopupWindow,也会出现另一个问题,即ListPopupWindow的ListView仅在您单击Spinner后创建。

但无法注册Spinner的OnClickListener,以便在显示后设置ListView属性。

您可以使用performClick覆盖创建自定义微调器,然后通过反射获取mPopup。并使用mPopup.getListView().setScrollbarFadingEnabled(false)

但是如果你打算创建一个自定义Spinner,我相信实现整个弹出窗口比使用反射更容易满足你的需求。

答案 1 :(得分:1)

感谢 @nandeesh 获取他/她的答案,感谢 @ Eng.Fouad 获取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); }
}

答案 2 :(得分:1)

我注意到“ setScrollbarFadingEnabled” java方法和“ fadeScrollbar” xml方法都不会对Spinner产生任何影响,因为Spinner的列表视图被包装在一个对话框中(弹出式窗口),因此这些属性不会到达列表视图。

但是实际上到达微调框列表视图的是主题。

所以只需创建一个这样的自定义主题:

<style name="App_SpinnerStyle" >
        <item name="android:fadeScrollbars">false</item>
</style>

像这样将其添加到微调器中:

android:popupTheme="@style/App_SpinnerStyle"

经过测试!

答案 3 :(得分:0)

经过初步调查后,我认为无法在Spinner中调用setScrollbarFadingEnabled(false);

我已经阅读了类Spinner.javaView.java的实现(最后一个实现了API16的setScrollbarFadingEnabled(boolean),问题就在于:

cache.scrollBar.setAlpha(255);

此时可能cache.scrollBar为空,我没有找到任何方法强制对此属性进行初始化。

管理此属性的大多数方法都是受保护的或私有的,因此我们不能只调用它们。

我会继续研究这个问题,以找到一个可能的解决方案,但就目前而言,考虑到还没有人回答这个问题,我认为这是不可能的。

答案 4 :(得分:0)

在您的应用主题或活动中:

  <item name="android:dropDownListViewStyle">@style/SpinnerStyle1</item>

声明SpinnerStyle1:

<style name="SpinnerStyle1" parent="Widget.AppCompat.ListView.DropDown">
        <item name="android:divider">@color/blackText</item>
        <item name="android:dividerHeight">1px</item>
          <item name="android:scrollbarAlwaysDrawVerticalTrack">true</item>
</style>

答案 5 :(得分:0)

由于访问微调框的底层second loop并不容易,因此我找到了一个简单的解决方案。

在styles.xml中创建样式,并将ListView设置为无穷大的值。

scrollbarFadeDuration

然后将其设置为微调器主题:

<style name="AlwaysEnableScrollBar" parent="Widget.AppCompat.ListView.DropDown">
    <item name="android:scrollbarFadeDuration">10000000</item>
</style>
相关问题