디자이너들 불만중 하나가 iOS처럼 왜 클릭이미지를 자동으로 생성해주지 못하냐여서 이번에 프로젝트 하면서


간단하게 한번 만들어 봤습니다. 처음에는 그냥 mutate()로 Drawable 정보만 바꾸어 컬러필터 적용하고


StateListDrawable을 만들었으나 StateListDrawable에서 적용을 하지 못하더군요 그래서 Bitmap을 추출하여


BitmapDrawable을 생성한다음 컬러필터를 적용하고 넣어줬습니다.


왜 굳이 ButtonDrawable로 Drawable을 감쌌는지는 setColorFilter() 오버라이드한 주석에 보시면 나와있습니다.


layout XML 에서 selector 구조 말고 그냥 일반 이미지 drawable 넣어주시고  static 메서드인


setupClickBackgroundDrawable(View v) 와 setupClickImageDrawable(ImageView imageView)로


설정하여 사용하시면 됩니다.


당장 급하게 사용할 용도로 만들어서 좀 엉망인데 개념만 참고하시면 다양하게 응용 가능하실겁니다.


 public class ButtonDrawable extends Drawable {
    
    private Drawable mDrawable;
    
    public ButtonDrawable(Drawable drawable) {
        mDrawable = drawable;
    }
    
    @Override
    public void draw(Canvas canvas) {
        mDrawable.draw(canvas);
    }

    @Override
    public int getOpacity() {
        return mDrawable.getOpacity();
    }

    @Override
    public void setAlpha(int alpha) {
        mDrawable.setAlpha(alpha);
    }
    
    @Override
    public void setBounds(Rect bounds) {
        mDrawable.setBounds(bounds);
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        // DrawableContainer 에서는 자신의 ColorFilter를 자식들에게 넣어주고
        // 그리기 때문에 해당 메서드를 구현하지 않는다.
    }
    
    public static void setupClickBackgroundDrawable(View v) {
        Bitmap bitmap = ((BitmapDrawable) v.getBackground()).getBitmap();
        v.setBackgroundDrawable(makeClickDrawable(v.getResources(), bitmap));
    }
    
    public static void setupClickImageDrawable(ImageView imageView) {
        Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
        imageView.setImageDrawable(makeClickDrawable(imageView.getResources(), bitmap));
    }
    
    private static Drawable makeClickDrawable(Resources res, Bitmap bitmap) {
        Drawable normal = new BitmapDrawable(res, bitmap);
        Drawable normalButton = new ButtonDrawable(normal);
        
        Drawable pressed = new BitmapDrawable(res, bitmap);
        pressed.setColorFilter(new LightingColorFilter(Color.LTGRAY, 1));
        Drawable pressedButton = new ButtonDrawable(pressed);
        
        StateListDrawable drawable = new StateListDrawable();
        drawable.addState(new int[] { -android.R.attr.state_pressed } , normalButton);
        drawable.addState(new int[] { android.R.attr.state_pressed } , pressedButton);
        return drawable;
    }
    
}