I'm making a custom calendar view which extends LinearLayout and has child views for each date. 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. But to handle click event, I have no idea how to find a child view which click happened.
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;
}
....
}
I resolved this by overriding 'onInterceptTouchEvent()' on MonthView, and posting the solution to help someone who would struggle with same issue. I implemented GestureDetector to change month on 'onFling()' like below codes.
@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;
}