22

我有一个包含很多元素的滚动视图

ScrollView scroller = (ScrollView)findViewById(R.id.scrollView);

我需要将 onClickListener 附加到滚动视图,所以我这样做

scroller.setOnClickListener(new OnClickListener() { 
            @Override
            public void onClick(View v) { 
                // This is all you need to do to 3D flip
                AnimationFactory.flipTransition(viewAnimator, FlipDirection.LEFT_RIGHT); 
            }

        });

但是当我触摸时,这不会被触发。有任何想法吗?

4

6 回答 6

14

最好的解决方案似乎是放入LinearLayoutScrollView设置setOnClickListener它。

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/myLayout"
        android:clickable="true"
        android:orientation="vertical">

       <!-- content here -->
   </LinearLayout>
</ScrollView>

在活动中:

LinearLayout lin = (LinearLayout) fragment.rootView.findViewById(R.id.myLayout);

lin.setOnTouchListener(new setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            // Whatever
        }
});
于 2014-11-13T17:11:15.860 回答
11

这是因为 的孩子ScrollView正在获取用户的触摸事件,而不是ScrollView. 您必须为 的android:clickable="false"每个子级设置属性才能使用。ScrollViewonClickListenerScrollView

否则,替代方法可能是onClickListener在每个 ScrollView 的子项上设置并处理它。

于 2013-05-27T16:06:44.873 回答
11

您需要setOnClickListener 直接在 ScrollView 的 child 上设置。

由于ScrollView只能有一个 child,您可以简单地使用这种方法:

ScrollView scrollView = //...

View.OnClickListener mOnClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        // ...
}

//Set the onClickListener directly on the ScrollView's child
scrollView.getChildAt(0).setOnClickListener(mOnClickListener);
于 2015-01-14T11:51:07.503 回答
2

2020 年 12 月 22 日更新

可悲的是,这也会在每个滚动事件之后触发。

这实际上是问题的答案,没有任何奇怪的情况,通过使用View.OnTouchListener而不是View.OnClickListenerScrollView并检测MotionEvent.ACTION_UP手指离开屏幕的位置。

为了确保它不是滚动,然后保存之前触摸屏的 x,y 值MotionEvent.ACTION_DOWN并将其与 的值进行比较MotionEvent.ACTION_UP。如果它们不相等,那么用户在离开屏幕之前肯定正在移动他们的手指(即滚动)。

int mXOld, mYOld; // field values to save the tap down on the ScrollView 

scrollView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {

        int x = (int) event.getX();
        int y = (int) event.getY();

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            mXOld = x;
            mYOld = y;
        } else if (event.getAction() == MotionEvent.ACTION_UP) {

            if (x == mXOld || y == mYOld) {  // detecting it's not a horizontal/vertical scrolling in ScrollView
                // HERE add the code you need when the ScrollView is clicked
                Toast.makeText(MainActivity.this, "Click", Toast.LENGTH_SHORT).show();
                return false;
            }
        }

        return false;
    }
});

原始答案:与问题不同的奇怪案例

我的问题有点不同,所以我想分享它..

我有一个ScrollView我必须使用match_parent它的宽度和高度;我有一个TextViewScrollView.

的文本TextView可以很长,所以它占据了整个高度ScrollView,有时它可以很短,所以顶部和底部会有空白区域。所以,OnClickListener每当TextView文本是简短,因为我希望空白区域也能检测到点击事件;而且OnClickListeneronScrollView也不起作用..

所以,我通过设置并放入代码解决了这个问题OnTouchListener,所以它可以通过将手指离开屏幕来模拟完整的点击。ScrollViewMotionEvent.ACTION_UP

private View.OnTouchListener mScrollViewTouchListener = new View.OnTouchListener() {
    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) { 
            // DO Something HERE...
        }
        return false;
    }
};
于 2020-06-10T22:19:23.363 回答
2

正如@Zain 指出的那样,有时需要为 Scrollview 的整个区域捕获 OnClick,而子项可能更小或不可见。为了规避被检测为 onClick 的滚动,我们使用了 GestureDetector:

final protected GestureDetector gestureDetector = new GestureDetector(getActivity(),
            new GestureDetector.SimpleOnGestureListener() {

                @Override
                public boolean onSingleTapUp(MotionEvent e) {
                    return true;
                }

            });

在 onCreateView

scrollView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if(gestureDetector.onTouchEvent(event)){
                    [do stuff]
                }

                return false;
            }
        });
于 2020-12-23T17:14:09.830 回答
0

我认为您可以自定义一个 ScrollView,覆盖 dispatchTouchEvent 方法,添加自定义 onClick 回调。

于 2020-06-23T05:56:01.093 回答