7

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

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)
4

6 回答 6

9

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

微调器显示的弹出窗口有一个滚动条。所以需要修改 spinner 显示的 ListView 的属性。但是 ListView 本身并没有被 Spinner 通过任何公共方法公开。

即使你通过反射得到ListPopupWindow,也会出现另一个问题,即ListPopupWindow的ListView只有在你点击Spinner之后才会创建。

但是 Spinner 的 OnClickListener 不能注册,显示后设置 ListView 属性。

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

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

于 2012-09-28T17:17:49.973 回答
1

感谢@nandeesh的回答,也感谢@Eng.Fouad在另一页上的回答。

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); }
}
于 2017-11-25T16:01:44.310 回答
0

经过初步调查,我认为不可能调用setScrollbarFadingEnabled(false);Spinner。

我已经阅读了 Class 的实现Spinner.javaView.java(最后一个实现setScrollbarFadingEnabled(boolean)了 API16 的,问题是这一行:

cache.scrollBar.setAlpha(255);

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

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

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

于 2012-09-28T11:47:44.003 回答
0

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

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

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

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

并将其添加到微调器中,如下所示:

android:popupTheme="@style/App_SpinnerStyle"

久经考验!

于 2019-11-23T06:41:28.223 回答
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>
于 2020-09-12T09:05:56.527 回答
0

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

在styles.xml 中创建一个样式,并设置scrollbarFadeDuration为一些无穷无尽的值。

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

然后在微调器主题中设置它:

<Spinner
    ...
    android:theme="@style/AlwaysEnableScrollBar"/>
于 2020-12-05T23:03:40.180 回答