简体   繁体   English

如何在父视图中处理子视图的触摸事件

[英]How to handle touch event for child view in parent view

I'm making a custom calendar view which extends LinearLayout and has child views for each date. 我正在制作一个自定义日历视图,它扩展了LinearLayout并为每个日期提供了子视图。 What I want to do is handling swipe and click, as you can imagine, swipe is for changing month and click is for selecting a date and showing new activity. 我想要做的是处理滑动和点击,你可以想象,滑动用于更改月份,点击用于选择日期和显示新活动。 To do this, I use GestureDetector on CalendarView and could make it work for swipe. 为此,我在CalendarView上使用GestureDetector,可以使其适用于滑动。 But to handle click event, I have no idea how to find a child view which click happened. 但是为了处理点击事件,我不知道如何找到发生了点击的子视图。

  1. Does anyone have any idea to resolve this? 有没有人有任何想法解决这个问题?
  2. What's the difference between return true and false on OnScroll(MotionEvent)? OnScroll(MotionEvent)上返回true和false之间的区别是什么?

Below is part of my codes. 以下是我的代码的一部分。

public class MonthView extends LinearLayout implements GestureDetector.OnGestureListener {

    public MonthView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        gestureDetector = new GestureDetector(this);
        initDateViews();
    }

    //other codes here
    ....

    private void initDateViews() {
        for(int i = 0; i < 42; i++) {
            DateView view = new DateView();
            //init date views and add to calendar view.
            ....
            calendar.Add(view);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Logger.debug(TAG, ">>> MonthView.onTouchEvent()");

        return gestureDetector.onTouchEvent(event);
    }

    @Override
    public boolean OnSingleTapUp(MotionEvent event) {
        // how can I find a child view to handle click event?
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        // right to left
        if (e1.getX() - e2.getX() > minSwipeDistance) {
            this.prevMonth();
        }
        // left to right
        else if(e2.getX() - e1.getX() > minSwipeDistance) {
            this.nextMonth();
        }
        // bottom to top
        else if(e1.getY() - e2.getY() > minSwipeDistance) {
            this.prevMonth();
        }
        //top to bottom
        else if(e2.getY() - e1.getY() > minSwipeDistance) {
            this.nextMonth();
        }

        return false;
    }

    ....
}

The boolean return value of on[GestureEvent] callbacks indicates whether or not the callback function consumed the event. on[GestureEvent]回调的布尔返回值指示回调函数是否消耗了该事件。 That is, in your onScroll implementation you would return true, because you are handling these events. 也就是说,在onScroll实现中,您将返回true,因为您正在处理这些事件。

However, onSingleTapUp should return false to indicate that you want the event to be passed on to the child views. 但是, onSingleTapUp应返回false以指示您希望将事件传递给子视图。

You should then register an OnClickListener that is able to handle the actual date for each child view in: 然后,您应该注册一个能够处理每个子视图的实际日期的OnClickListener

private void initDateViews() {
    for(int i = 0; i < 42; i++) {
        DateView view = new DateView();
        //init date views and add to calendar view.
        ....

        // register onClickListener for e.g. date
        view.setOnCLickListener(new DateOnClickListner(date))
        calendar.Add(view);
    }
}

With an OnclickListener implementation like 使用OnclickListener实现

class DateOnClickListner(Date date) extends View.OnClickListener {
    public void onClick(View v) {
        ...
    }
}

I resolved this by overriding 'onInterceptTouchEvent()' on MonthView, and posting the solution to help someone who would struggle with same issue. 我通过覆盖MonthView上的'onInterceptTouchEvent()'来解决这个问题,并发布解决方案以帮助那些会遇到同样问题的人。 I implemented GestureDetector to change month on 'onFling()' like below codes. 我实现了GestureDetector来改变'onFling()'上的月份,就像下面的代码一样。

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    boolean result = gestureDetector.onTouchEvent(event);

    return result;
}

@Override
public boolean onDown(MotionEvent e) {
    return false;
}

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    // right to left
    if (e1.getX() - e2.getX() > minSwipeDistance) {
        nextMonth();
    }
    // left to right
    else if(e2.getX() - e1.getX() > minSwipeDistance) {
        prevMonth();
    }
    // bottom to top
    else if(e1.getY() - e2.getY() > minSwipeDistance) {
        nextMonth();
    }
    //top to bottom
    else if(e2.getY() - e1.getY() > minSwipeDistance) {
        prevMonth();
    }

    return true;
}

@Override
public void onLongPress(MotionEvent e) {
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
    return false;
}

@Override
public void onShowPress(MotionEvent e) {
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在父视图中处理触摸,但在子视图中处理单击事件 - Handle touch in parent view but Handle Click event in child 如何在父视图的触摸监听器中消费子视图的触摸事件? - How to consume child view's touch event in parent view's touchlistener? 如何在父视图(ScrollView)中处理子视图(CustomView)的TouchEvent? - How to Handle TouchEvents for Child View(CustomView) in Parent View (ScrollView)? Android-在子视图触摸上忽略父视图触摸 - Android - ignore parent view touch on child view touch 如何处理listview项目视图的子视图的click事件? - How to handle a click event of a child view of a listview item view? 仅在子视图区域上被触摸时,如何触发子触摸事件。 在其他情况下,需要触发父母的触摸事件 - How to trigger Child's touch event only when touched on a child view area. In other scenarios, parent's touch event needs to be triggered 如何在子视图组和父视图组触摸事件之间变化 - How to vary between child and parent view group touch events 如何处理触摸事件以下拉文本视图 - How to Handle Touch Event to pull down the text view 如何仅在不透明(可见)区域上处理自定义视图触摸事件 - How to handle custom view touch event only on opaque(visible) area 父级和子级视图的单击事件 - On Click event for Parent and Child view
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM