이미지 버튼 같은 것을 만들려고 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);
}
}
}
}
지금 해결했는데요.. 이건 ClickListener interface를 따로 구현해줘야 합니다.
package com.android.custom;
public interface ClickListener {
/**
* This method is called when the button is clicked.
*
* @param button
* The instance of the button that was clicked.
*/
void onClick(CustomImageButton button);
}
이런 클릭 인터페이스를 아래 View.OnClickListener대신에 사용해줘야 합니다.
그리고 아래 리스너를 사용하는 부분 2군데도 역시 같게 수정해줘야 하구요,
private View.OnClickListener listener = null;