2015-09-05 70 views
4

我正在製作一個自定義日曆視圖,該視圖擴展了LinearLayout並具有每個日期的子視圖。我想要做的就是處理滑動和點擊,你可以想象,滑動是爲了改變月份,點擊是爲了選擇一個日期並顯示新的活動。爲此,我在CalendarView上使用GestureDetector並可以使其適用於滑動。但要處理點擊事件,我不知道如何找到發生點擊的子視圖。如何在父視圖中處理子視圖的觸摸事件

  1. 有沒有人有任何想法來解決這個問題?
  2. OnScroll(MotionEvent)上返回true和false有什麼區別?

以下是我的部分代碼。

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; 
    } 

    .... 
} 

回答

0

我通過重寫「onInterceptTouchEvent解決了這個()',然後發佈解決方案以幫助那些會遇到同樣問題的人。 我實施了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; 
} 
1

on[GestureEvent]回調布爾返回值表示的回調函數是否不消耗事件。也就是說,在您的onScroll實現中,您將返回true,因爲您正在處理這些事件。

但是,onSingleTapUp應返回false以表示您希望將事件傳遞給子視圖。

然後,您應該註冊一個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); 
    } 
} 

隨着OnclickListener實現像

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

謝謝你的提醒,但實際上這似乎是我的,我想對孩子查看日曆視圖和的onClick()使用的onTouchEvent()原代碼非常相似。然而,這並沒有像我在孩子觀點開始時所預期的那樣有效。因爲子視圖通過onClick()回調方法消費OnDown事件。這就是爲什麼我決定在日曆視圖上使用GestureDetector來處理滑動和點擊。 – user3110409

相關問題