MotionEvent处理,滚动型的机器人 [英] MotionEvent handling in ScrollView in Android

查看:185
本文介绍了MotionEvent处理,滚动型的机器人的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图找出在ScrollViews MotionEvents在Android上的行为,有件事情我想不通。

I've been trying to figure out the behavior of MotionEvents in ScrollViews in Android and there's something i can't figure out.

作为一个例子,我做,有一个滚动型它的内部和滚动型具有的LinearLayout它内部的活动。我实现了自己的班级有过接触的相关功能控制:

As an example I made an Activity that has a ScrollView inside of it and the ScrollView has a LinearLayout inside of it. I implemented my own classes to have control over the touch-related functions:

    public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MyInnerLayout inner = new MyInnerLayout(getApplicationContext());
        MyLayout layout = new MyLayout(getApplicationContext());

        layout.addView(inner,new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
        setContentView(layout);

    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.i("scrollview","activity dispatchTouchEvent "+ev.getAction());
        return super.dispatchTouchEvent(ev);
    };

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        Log.i("scrollview","activity on touch "+ev.getAction());
        return super.onTouchEvent(ev);
    }




    public class MyLayout extends ScrollView {

        public MyLayout(Context context) {
            super(context);
        }

        @Override
        public boolean dispatchKeyEvent(KeyEvent ev) {
            Log.i("scrollview","layout dispatchKeyEvent "+ev.getAction());
            return super.dispatchKeyEvent(ev);
        }

        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            Log.i("scrollview","layout onInterceptTouchEvent "+ev.getAction());
            return false;
        }

        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            Log.i("scrollview","layout on touch "+ev.getAction());
            return false;
        }

    }

    public class MyInnerLayout extends LinearLayout{

        public MyInnerLayout(Context context) {
            super(context);
        }

        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            Log.i("scrollview","inner layout dispatchTouchEvent "+ev.getAction());
            return true;
        }

        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            Log.i("scrollview","inner layout onInterceptTouchEvent "+ev.getAction());
            return true;
        }

        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            Log.i("scrollview","inner layout on touch "+ev.getAction());
            return true;
        }

    }

}

当我点击屏幕上的任何地方我得到这个日志:

When I click anywhere on the screen I get this log:

10-14 18:11:48.631: I/scrollview(14906): activity dispatchTouchEvent 0
10-14 18:11:48.631: I/scrollview(14906): layout onInterceptTouchEvent 0
10-14 18:11:48.631: I/scrollview(14906): layout on touch 0
10-14 18:11:48.631: I/scrollview(14906): activity on touch 0
10-14 18:11:48.647: I/scrollview(14906): activity dispatchTouchEvent 1
10-14 18:11:48.647: I/scrollview(14906): activity on touch 1

这意味着触摸事件并没有使一直到滚动视图内侧的内布局。 但是当我在滚动型更改为的LinearLayout(只是简单地改变它的延伸),事件下降到内部布局:

that means that the touch event didn't make the way down to the inner layout inside the scrollview. however when I change the ScrollView to a LinearLayout (simply just change it in the extends), the event goes down to the inner layout:

10-14 18:24:08.975: I/scrollview(15115): activity dispatchTouchEvent 0
10-14 18:24:08.975: I/scrollview(15115): layout onInterceptTouchEvent 0
10-14 18:24:08.975: I/scrollview(15115): inner layout dispatchTouchEvent 0
10-14 18:24:09.045: I/scrollview(15115): activity dispatchTouchEvent 1
10-14 18:24:09.045: I/scrollview(15115): layout onInterceptTouchEvent 1
10-14 18:24:09.045: I/scrollview(15115): inner layout dispatchTouchEvent 1

我看着<一href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/2.2_r1.1/android/widget/ScrollView.java"相对=nofollow>的滚动型类源$ C ​​$ c和唯一的触摸相关的方法,它重写都是我overrided自己。所以,我不明白是什么让的LinearLayout和滚动型的行为之间的区别。

I looked in the source code of the ScrollView class and the only touch-related methods that it overrides are the ones I overrided myself. So I don't understand what makes the difference between the behavior of the LinearLayout and the ScrollView.

推荐答案

也许你已经想通了,为什么在行为上面,但以防万一,你不这样做,在这里不用的原因。

Maybe you already figured out why the behaviour above, but just in case you don't, here goes the reason.

概述

onInterceptTouchEvent()被称为自上而下(从父母到孩子),使一个视图是由儿童正在处理前拦截动作事件。

The onInterceptTouchEvent() are called top-down (from parent to child) enabling one view to intercept the motion event before being handled by a child.

的onTouchEvent()被称为自底向上(从子到父),直到其中一人消费,并循环做完。

The onTouchEvent() are called down-top (from child to parent) until one of them consum it and the cycle finishs.

A 滚动型拦截 MotionEvent 来检查它是否应该将它们传递给孩子之前滚动视图。如果滚动应该要进行钻削,该事件被消耗和子视图什么也看不见。

A ScrollView intercepts MotionEvent to check if it should scroll the view before passing them to the child. If the scroll should to be perfomed, the event is consumed and child view sees nothing.

的LinearLayout 的情况下,没有任何理由的情况下应在 onInterceptTouchEvent被消耗(),并始终被传递到子图。

In the case of LinearLayout, there is no reason why the event should be consumed during onInterceptTouchEvent(), and is always passed to the child view.

什么是发生在你的code

由于 MyInnerLayout 是空的滚动型总是消耗 MotionEvent

如果,例如,您设置的内部布局backgound是这样的:

If, for example, you set the inner layout backgound like this:

    MyInnerLayout inner = new MyInnerLayout(getApplicationContext());
    inner.setBackground(getResources().getDrawable(R.drawable.ic_launcher));
    MyLayout layout = new MyLayout(getApplicationContext());

您会看到,如果你接触过的背景图像的情况下将达到孩子。如果你的背景图像外触,该事件将被占用的滚动型

you will see that if you touch over the background image the event will reach the child. If you touch outside the background image, the event will be consumed by the ScrollView.

希望这有助于。

问候。

这篇关于MotionEvent处理,滚动型的机器人的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆