android code

canvas에서 selector 적용하기

paulaner80 2016. 8. 10. 10:27
반응형

결론적으로 

        mDeleteDrawable.setState(StateSet.WILD_CARD);

        mDeleteDrawable.setState(View.PRESSED_STATE_SET);

를 사용하면 됩니다.

그리고 MainActivity에 myView.setClickable(true);가 있어야 MyView의 onTouchEvent가 제대로 동작합니다.



1. selector drawable 

 그냥 이미지 파일을 사용해도 되지만 구하기 귀찮아서 Android studio에서 제공하는 벡터 이미지로 만들어봄.


ic_clear_black_24dp.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"

        android:width="56dp"

        android:height="56dp"

        android:viewportWidth="24.0"

        android:viewportHeight="24.0">

    <path

        android:fillColor="#FF000000"

        android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>

</vector>


ic_clear_green_24dp.xml 

(ic_clear_black_24dp.xml 에서 fill color마 다름

<vector xmlns:android="http://schemas.android.com/apk/res/android"

        android:width="56dp"

        android:height="56dp"

        android:viewportWidth="24.0"

        android:viewportHeight="24.0">

    <path

        android:fillColor="#FF00ff00"

        android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>

</vector>


ic_clear_back_24dp_selector.xml

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true" android:drawable="@drawable/ic_clear_green_24dp"/>

    <item android:drawable="@drawable/ic_clear_black_24dp"/>

</selector>



2. MyView class


public class MyView extends View {


    Drawable mDeleteDrawable;

    float mDeleteDrawableWidth;


    float mDeleteMinX;

    float mDeleteMinY;

    float mDeleteMaxX;

    float mDeleteMaxY;


    public MyView(Context context) {

        super(context);

        initPaints();

    }


    public MyView(Context context, AttributeSet attrs) {

        super(context, attrs);

        initPaints();

    }


    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {

        super(context, attrs, defStyleAttr);

        initPaints();

    }


    private void initPaints(){


        this.mDeleteDrawableWidth = convertDpTpPixel(150.0f,getContext()) ;


        float left = 300f;

        float top = 300f;


        mDeleteMinX = left -mDeleteDrawableWidth/2;

        mDeleteMinY = top -mDeleteDrawableWidth/2;

        mDeleteMaxX = left + mDeleteDrawableWidth/2;

        mDeleteMaxY = top + mDeleteDrawableWidth/2;



        this.mDeleteDrawable = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_clear_back_24dp_selector, null);

        this.mDeleteDrawable.setBounds((int)mDeleteMinX, (int)mDeleteMinY, (int)mDeleteMaxX, (int)mDeleteMaxY);


    }


    @Override

    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);


        mDeleteDrawable.draw(canvas);


    }


    private float convertDpTpPixel(float dp, Context context){


        Resources  resources = context.getResources();

        DisplayMetrics metrics = resources.getDisplayMetrics();

        float px = dp * ((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);

        return px;

    }


    private boolean isDeletButtonClick(float x, float y){


        RectF rectF = new RectF(mDeleteMinX, mDeleteMinY, mDeleteMaxX, mDeleteMaxY);


        return rectF.contains(x, y);


    }


    @Override

    public boolean onTouchEvent(MotionEvent event) {


        float x = event.getX();

        float y = event.getY();


        mDeleteDrawable.setState(StateSet.WILD_CARD);


        if(event.getAction() == MotionEvent.ACTION_DOWN){

            if(isDeletButtonClick(x, y)){

                mDeleteDrawable.setState(View.PRESSED_STATE_SET);

                invalidate();

            }else{

                invalidate();

            }

        }


        if(event.getAction() == MotionEvent.ACTION_UP){

            invalidate();

        }



        return super.onTouchEvent(event);

    }




3. main activity

myView.setClickable(true);가 있어야 MyView의 onTouchEvent가 제대로 동작함

public class MainActivity extends AppCompatActivity {

    RelativeLayout rl_myroot;


    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);


        rl_myroot = (RelativeLayout)findViewById(R.id.rl_myroot);


        MyView myView = new MyView(this);

        RelativeLayout.LayoutParams params

                = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,

                                                  ViewGroup.LayoutParams.MATCH_PARENT);

        myView.setLayoutParams(params);

        myView.setClickable(true);

        rl_myroot.addView(myView);

    }

}


'android code' 카테고리의 다른 글

android canvas 지우개  (0) 2016.08.25
PopupWindow 예제  (0) 2016.08.23
안드로이드 파일 복사 퍼미션  (0) 2016.07.31
서버에 이미지 업로드 하는 예제  (0) 2016.07.29
SparseArray for 문 돌리는 법  (0) 2016.07.27