在Android上,有没有办法禁用Spinner的长按行为?

use*_*854 11 android spinner long-press

默认的微调器行为是当它"关闭"时,长按它将"打开"它并显示下拉视图.我发现这种行为对用户来说可能是非常有问题的.例如,如果他们试图在屏幕上滚动某些内容,并碰巧"抓住"一个有微调器的地点,那么它会在一秒左右打开下拉视图而不是滚动,并且用户是基本上用手指放在其中一个下拉选项上(他们现在可能会意外按下).

所以,我想禁用那个长按行为,并且只在单击它时让旋转器"打开",而不是长按.那可能吗?

Dav*_*and 5

如果您只需要恢复标准点击行为,这是Jordi答案的更简单,更紧凑的版本:

spinner.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                v.performClick();
            }
            return true;
        }
    });
Run Code Online (Sandbox Code Playgroud)

进一步的想法

这种行为也让我烦恼.经过调查,似乎它有一个名字:拖动打开.您可以在AppCompatSpinner#onTouchEvent()方法源中看到它是如何定义的.

我看到这种强制行为的一些问题(以及某些人想要禁用它的原因):

  1. 它允许用户在微调器中选择禁用的值.通过长按,拖动和释放,您可以选择通过正常交互甚至无法选择的值(点击打开+点击选择)
  2. 作为#1的结果,它也可以非常容易地使Espresso测试失败.实际上,在Espresso中,点击的持续时间相当不稳定,一次点击可以很快变成长按和选择交互.
  3. 最后,这里最大的问题是没有方法/ XML属性来禁用"拖动打开"行为......

让我们解决它!

我在AOSP问题跟踪器上开了一张与此相关的票:#228953.如果我遗漏任何东西,请随意关注它,或发表评论.


use*_*854 3

所以,我想出了一个相对简单的方法来做到这一点,尽管它不是很优雅。基本上,我在 Spinner 顶部创建了一个透明的覆盖视图,并将其设置为具有仅触发 Spinner 的单击的 OnClickListener。

XML:

    <Spinner 
        android:id="@+id/spinner"
        android:layout_width="match_parent" 
        android:layout_height="40dip" />

    <View android:id="@+id/spinner_overlay"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/spinner" 
        android:layout_alignRight="@id/spinner"
        android:layout_alignTop="@id/spinner" 
        android:layout_alignBottom="@id/spinner"  />
Run Code Online (Sandbox Code Playgroud)

爪哇:

        View spinnerOverlay = findViewById(R.id.spinner_overlay);
        spinnerOverlay.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {
                spinner.performClick();
            }

        });
Run Code Online (Sandbox Code Playgroud)