java 用于自定义视图的 Android onTouchEvent

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34550303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 23:01:37  来源:igfitidea点击:

Android onTouchEvent for custom view

javaandroid

提问by yawers

I created a service that displays a custom Viewinside a custom LinearLayout. The service works fine, and the Viewis shown on the screen, but I cannot get the Viewor the LinearLayoutto receive any touch events (I just want either one of them to receive touch events, I don't care which). This is what I have:

我创建了一个View在 custom中显示自定义的服务LinearLayout。该服务工作正常,并且View显示在屏幕上,但我无法获得ViewLinearLayout来接收任何触摸事件(我只希望其中一个接收触摸事件,我不在乎哪个)。这就是我所拥有的:

MyLayout.java

我的布局.java

public class MyLayout extends LinearLayout {

    public MyLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public MyLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        onTouchEvent(ev);
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Toast.makeText(this.getContext(), "Touched layout", Toast.LENGTH_SHORT).show();
        Log.d("TOUCH", "Touched layout");
        return true;
    }
}

MyView.java

我的视图

public class MyViewextends View{

    public MyView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Toast.makeText(this.getContext(), "Touched View", Toast.LENGTH_SHORT).show();
        Log.d("TOUCH", "Touched View");
        return true;
    }
}

回答by Mhmd Salem

From the SDK Documentation:

来自 SDK 文档:

onTouch() - This returns a boolean to indicate whether your listener consumes this event. The important thing is that this event can have multiple actions that follow each other. So, if you return false when the down action event is received, you indicate that you have not consumed the event and are also not interested in subsequent actions from this event. Thus, you will not be called for any other actions within the event, such as a finger gesture, or the eventual up action event.

onTouch() - 这将返回一个布尔值来指示您的侦听器是否使用此事件。重要的是这个事件可以有多个相互跟随的动作。因此,如果您在收到 down 操作事件时返回 false,则表明您尚未消费该事件,并且对该事件的后续操作也不感兴趣。因此,您不会因为事件中的任何其他动作而被调用,例如手指手势或最终的向上动作事件。

You need to return true when the ACTION_DOWN event is triggered to indicate that you are interested in the subsequent calls relating to that same event.

当 ACTION_DOWN 事件被触发时,您需要返回 true 以表明您对与同一事件相关的后续调用感兴趣。

If you need to write an Android onTouchEvent method inside a View class, here's some example source code (boilerplate/skeleton code) that shows how to implement this method, including how to use the MotionEvent in the method, and how to get the x and y location of the touch event:

如果您需要在 View 类中编写 Android onTouchEvent 方法,这里有一些示例源代码(样板/骨架代码),展示了如何实现此方法,包括如何在方法中使用 MotionEvent,以及如何获取 x 和y 触摸事件的位置:

public boolean onTouchEvent(MotionEvent event) {

    int eventAction = event.getAction();

    // you may need the x/y location
    int x = (int)event.getX();
    int y = (int)event.getY();

    // put your code in here to handle the event
    switch (eventAction) {
        case MotionEvent.ACTION_DOWN:
            break;
        case MotionEvent.ACTION_UP:
            break;
        case MotionEvent.ACTION_MOVE:
            break;
    }

    // tell the View to redraw the Canvas
    invalidate();

    // tell the View that we handled the event
    return true;

}

I commented the code, and I think it shows the most common way this method is used, so I won't bother to add any explanation here. I showed how to get the x and y location of the touch event because you'll generally want to check to see where the event occurred.

我对代码进行了注释,我认为它显示了该方法的最常见使用方式,因此我不会在这里添加任何解释。我展示了如何获取触摸事件的 x 和 y 位置,因为您通常希望查看事件发生的位置。

So, in summary, if you wanted to see an example Android onTouchEvent method (in a View class), I hope this example is helpful.

因此,总而言之,如果您想查看一个示例 Android onTouchEvent 方法(在 View 类中),我希望这个示例对您有所帮助。

ref : http://alvinalexander.com/android/android-ontouchevent-example-method-view-class

参考:http: //alvinalexander.com/android/android-ontouchevent-example-method-view-class

回答by Floern

Your View is not receiving any touch events because your custom LinearLayout is blocking the events as it does not dispatch the events to its child Views.

您的视图没有收到任何触摸事件,因为您的自定义 LinearLayout 正在阻止事件,因为它不会将事件分派到其子视图。

I'm not quite sure why you are overriding the methods onInterceptTouchEvent()and onTouchEvent()in your MyLayout, but if you do not require them, I would suggest to remove them both, so the layout has its default behavior regarding processing touch events.

我不太确定你为什么要覆盖方法onInterceptTouchEvent()onTouchEvent()你的MyLayout,但如果你不需要它们,我建议将它们都删除,因此布局具有处理触摸事件的默认行为。

If you really need them, you may have to call the supermethods of each:

如果你真的需要它们,你可能需要调用super每个的方法:

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return super.onInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    Toast.makeText(this.getContext(), "Touched layout", Toast.LENGTH_SHORT).show();
    Log.d("TOUCH", "Touched layout");
    return super.onTouchEvent(event);
}