이미지 버튼 같은 것을 만들려고 Custom View를 작성하고 있습니다.

근데 이상하게 Touch Event는 오는데 OnClick 이벤트가 안오네요.

Custom View에서는 원래 OnClick Event 안오는건가요?

아래쪽에 제 소스입니다.


public class CustomImageButton extends View
{
    //Namespaces to read attributes
    private static final String CONTROL_NS = "CustomImageButton";
    private static final String ANDROID_NS = "http://schemas.android.com/apk/res/android";

    // Attribute names
    private static final String ATTR_PATH_TEXT = "path";
    private static final String ATTR_LABEL_TEXT = "label";   
 
 private final static int WIDTH_PADDING = 8;
 private final static int HEIGHT_PADDING = 10;

 private final String label;
 private final int imageResId;
 private final Bitmap image;
 
 private final String TAG = "BB LOG";

 private final InternalListener listenerAdapter = new InternalListener();

 /**
 Constructor.

 @param context
  Activity context in which the button view is being placed for.

 @param resImage
  Image to put on the button. This image should have been placed
  in the drawable resources directory.

 @param label
  The text label to display for the custom button.
 */

 /*
 public CustomImageButton(Context context)
 {
     super(context);  
 }
 */

 public CustomImageButton(Context context, AttributeSet attrs)
 {
     this(context, attrs, 0);
 }
 
 public CustomImageButton(Context context, AttributeSet attrs, int defStyle)
 {
     super(context, attrs, defStyle);
    
  String res_string = attrs.getAttributeValue(CONTROL_NS, ATTR_PATH_TEXT);
  String label_string = attrs.getAttributeValue(CONTROL_NS, ATTR_LABEL_TEXT);    
  
        int res_id = getResources().getIdentifier(res_string, "drawable", getContext().getPackageName()); 
  
  this.label = label_string;
  this.imageResId = res_id;
  this.image = BitmapFactory.decodeResource(context.getResources(), imageResId);
  
  setFocusable(true);
  setBackgroundColor(Color.WHITE);
 
  setOnClickListener(listenerAdapter);
  setClickable(true);     
  
  Log.w(TAG, "CustomView("+context+","+attrs+")");
 }

    /*
     * xml 로 부터 모든 뷰를 inflate 를 끝내고 실행된다.
     *
     * 대부분 이 함수에서는 각종 변수 초기화가 이루어 진다.
     *
     * super 메소드에서는 아무것도 하지않기때문에 쓰지 않는다.
     */
    @Override
    protected void onFinishInflate()
    {
        setClickable(true);
        Log.w(TAG, "onFinishInflate()");
    }
   
    /*
     * 이 view 에 touch 가 일어날때 실행됨.
     *
     * 기본적으로 touch up 이벤트가 일어날때만 잡아내며
     * setClickable(true) 로 셋팅하면 up,move,down 모두 잡아냄
     */
    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        //Log.w(TAG,"onTouchEvent("+event+")");
        switch(event.getAction())
        {
        case MotionEvent.ACTION_UP:
            //backgroundColor = Color.RED;
            //text = tempText;
            break;
        case MotionEvent.ACTION_DOWN:
            //backgroundColor = Color.YELLOW;
            //tempText = text;
            //text = "Clicked!";
            break;
        case MotionEvent.ACTION_MOVE:
            //backgroundColor = Color.BLUE;
            //text = "Moved!";
            break;
        }
        invalidate();
        return super.onTouchEvent(event);
    }

 /**
  The method that is called when the focus is changed to or from this
  view.
  */
 @Override 
 protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect)
 {
  Log.w(TAG, "onFocusChanged()");
  if (gainFocus == true)
  {
   this.setBackgroundColor(Color.rgb(255, 165, 0));
  }
  else
  {
   this.setBackgroundColor(Color.WHITE);
  }
 }

 /**
 * Method called on to render the view.
 */
 @Override 
 protected void onDraw(Canvas canvas)
 {
  Paint textPaint = new Paint();
  textPaint.setColor(Color.BLACK);
  canvas.drawBitmap(image, WIDTH_PADDING / 2, HEIGHT_PADDING / 2, null);
  canvas.drawText(label, WIDTH_PADDING / 2, (HEIGHT_PADDING / 2) +
    image.getHeight() + 8, textPaint);
 }
 
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
 {
  setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
 }
 
 private int measureWidth(int measureSpec)
 {
  int preferred = image.getWidth() * 2;
  return getMeasurement(measureSpec, preferred);
 }
 
 private int measureHeight(int measureSpec)
 {
  int preferred = image.getHeight() * 2;
  return getMeasurement(measureSpec, preferred);
 }
 
 private int getMeasurement(int measureSpec, int preferred)
 {
   int specSize = MeasureSpec.getSize(measureSpec);
  int measurement = 0;
 
  switch(MeasureSpec.getMode(measureSpec))
  {
   case MeasureSpec.EXACTLY:
     // This means the width of this view has been given.
    measurement = specSize;
   break;
   case MeasureSpec.AT_MOST:
     // Take the minimum of the preferred size and what
    // we were told to be.
    measurement = Math.min(preferred, specSize);
   break;
   default:
    measurement = preferred;
   break;
  }
  return measurement;
 }
 
 /**
  * Sets the listener object that is triggered when the view is clicked.
  *
  * @param newListener
  *        The instance of the listener to trigger.
  */
 @Override 
 public void setOnClickListener(View.OnClickListener newListener)
 {
  listenerAdapter.setListener(newListener);
 }
 
 /**
 * Returns the label of the button.
 */
 public String getLabel()
 {
  return label;
 }

 /**
 * Returns the resource id of the image.
 */
 public int getImageResId()
 {
  return imageResId;
 }
 
 /**
 * Internal click listener class. Translates a view’s click listener to
 * one that is more appropriate for the custom image button class.
 *
 * @author Kah
 */
 private class InternalListener implements View.OnClickListener
 {
  private View.OnClickListener listener = null;

  /**
  * Changes the listener to the given listener.
  *
  * @param newListener
  *        The listener to change to.
  */
  public void setListener(View.OnClickListener newListener)
  {
   listener = newListener;
  }
 
  @Override
  public void onClick(View v)
  {
   if (listener != null)
   {
    listener.onClick(CustomImageButton.this);
   }
  }
 }
}