본문 바로가기
IT기술(코딩)/안드로이드스튜디오

안드로이드 스튜디오 핀치 완벽 함수! 그냥 복붙해서 인자만 넣고 갖다써요. 이미지가 크면 화면크기에 맞춰져서 나옵니다. 이미지 확대 축소 기능 핀지 자바버전 슬라이드 무시, 스크롤 무시..

by 크리에이트매이커 2022. 1. 13.
반응형

안녕하세요 여러분..

오늘은 앱을 만들때 거의 필수적인 이미지 확대 축소 기능소스를 넣어볼게요~

아예 함수로 만들었으니 복붙하고 쓰셔도 될듯해여.

각설하고 바로 소스코드 들어갑니다.

adimages = (ImageView)adview.findViewById(R.id.adimage); //이미지 뷰 입니다.


//이미지 뷰를 MATRIX로 하면 이미지 원본 크기로 나오기 떄문에 크기 조정이 필요할 수 도 있습.
Display display = getActivity().getWindowManager().getDefaultDisplay(); 
        Point size = new Point();
        display.getSize(size);
        int width = size.x;
        int height = size.y;
        
        //bitmapimage는 이미 가져왔다는 가정하에 쓴 코드
        if(bitmapimage.getWidth() > width) {
                float scale = (float)width / (float)bitmapimage.getWidth();
                float fitwidth = (float) width;
                float fitheight = (float)bitmapimage.getHeight()*scale;
                Bitmap fitbitmap = Bitmap.createScaledBitmap(bitmapimage, (int)fitwidth, (int)fitheight, true);
                adimages.setImageBitmap(fitbitmap);
            }else{
                adimages.setImageBitmap(bitmapimage);
            }

        adimages.setScaleType(ImageView.ScaleType.MATRIX); //이걸 해줘야 핀치 가능
        
        //여기부터 이미지에 손 갖다 댔을때 반응하는 터치리스터 함수
        adimages.setOnTouchListener(new View.OnTouchListener (){
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (v.equals(adimages)) {
                    int action = event.getAction();
                    switch (action & MotionEvent.ACTION_MASK) {
                        case MotionEvent.ACTION_DOWN:
                            donwSingleEvent(event);
                            Log.d("TAG","touched : " + event.getPointerCount());
                            break;
                        case MotionEvent.ACTION_MOVE:
							//아래 disallowInterceptTouchEvent를 해줘야 스코롤, 슬라이드를 무시하고 핀치, 이동 가능
                            //스크롤이, 슬라이드 필요시 이 기능 위치를 조건부에 줘서 상황에따라 다 될 수 있게 하면 됩.
                            v.getParent().requestDisallowInterceptTouchEvent(true);
                            if(event.getPointerCount()==2){
                                touchMode = TOUCH_MODE.MULTI;
                            }else if(event.getPointerCount()==1) {
                                touchMode = TOUCH_MODE.SINGLE;
                            }
                            if (touchMode == TOUCH_MODE.SINGLE) {
                                moveSingleEvent(event); //사진 이동
                                Log.d("TAG","singlemove :"+ event.getPointerCount());
                            } else if (touchMode == TOUCH_MODE.MULTI) {
                                moveMultiEvent(event); //사진 확대
                                Log.d("TAG","multymove :"+ event.getPointerCount());
                            }else{
                                touchflage = 0;
                            }

                            break;

                        case MotionEvent.ACTION_UP: //손가락 땟을때
                        case MotionEvent.ACTION_POINTER_UP: //이것도 손가락 떗을떄
                            i = 0;
                            touchMode = TOUCH_MODE.NONE;
                            Log.d("TAG","testtouch");
                            break;
                    }
                }
                return true;

            }
        });


// 여긴 클래스로 따로 추가해서 필요할 때마다 쓰면 되여. 
//(그냥 클래스 안에 함수들만 빼서 onCreateView 함수 밖에다 선언하고 써도 돼여.)
//(참고로 위 코드는 클래스로 안쓰고 그냥 함수로 빼서 쓴 코드입니다)
public class matrixfunction{

	private PointF getMidPoint(MotionEvent e) {

            float x = (e.getX(0) + e.getX(1)) / 2;
            float y = (e.getY(0) + e.getY(1)) / 2;

            return new PointF(x, y);
        }

        private float getDistance(MotionEvent e) {
            float x = e.getX(0) - e.getX(1);
            float y = e.getY(0) - e.getY(1);
            return (float) Math.sqrt(x * x + y * y);
        }

    private void donwSingleEvent(MotionEvent event) {
        savedMatrix.set(matrix);
        startPoint = new PointF(event.getX(), event.getY());
    }

    private void moveSingleEvent(MotionEvent event) {
        matrix.set(savedMatrix);
        matrix.postTranslate(event.getX() - startPoint.x, event.getY() - startPoint.y);
        adimages.setImageMatrix(matrix);
        Log.d("TAG", "movemove : " +event.getX() +","+event.getY());
    }

 
    private void moveMultiEvent(MotionEvent event) {
        float newDistance = getDistance(event);

 // 지속적인 핀지를 위한 핀치 플래그라 생각하면 돼여
        if(i != 1){
            oldDistance = newDistance;
            i = 1;
        }
        if (newDistance > 10f) {
            matrix.set(savedMatrix);
            midPoint = getMidPoint(event);
            float scale = newDistance / oldDistance;
            matrix.postScale(scale, scale, midPoint.x, midPoint.y);


            Log.d("TAG", "distance : " + oldDistance +","+ newDistance);



            adimages.setImageMatrix(matrix);

        }
        
   }

이정도면 다들 할 수 있을거라 생각합니다!!

 

제가 다 짠건 아니고 저도 어디서 공부하고 비슷하게 짠거라  주석이랑 코드 보면 서 얜 왜이렇게 짯나 보세여~

반응형