본문 바로가기

아옳옳의 코딩공부/아옳옳의 안드로이드스튜디오

2021-03-17 안드로이드 스튜디오( 태스크3 , 사용자 이벤트 처리와 리소스 활용 )

728x90
반응형

FLAG_ACTIVITY_RESET_TASK_NEEDED

같은거 같지만 의미가 다르다 최신실행앱으로 재실행 하게 되면 탑 액티비티로 복귀 한다 

 

그런데 다른점은 매니패스트에 clearTaskOnLaunch 를 적어주게 되면 상위 액티비티를 정리해준다 

앱을 다시 실행한듯한 느낌을 줄때 사용을 한다 

 

finishOnTaskLaunch (NoHistory 랑 비슷 ) 이것은 앱을 다시 실행 했을때 그 액티비티만 제거됨 

 

clearTaskOnLaunch는 루트부터 실행 하지만 이건 설정된 액티비티부터 탑까지 제거 

 


사용자 이벤트 처리와 리소스 활용

지금 까지 많이 사용해본것이 터치 리스너 이다 하지만 터치 리스너 말고도 많은 것들이 있는데 한번 살펴 보자 

 

대표적인 이벤트로는 아래의 것들이 있다 

터치 이벤트 

-화면을 손가락으로 누를 때 발생하는 이벤트 (터치리스너 ) 

 

키 이벤트

-키패드나 하드웨어 버튼을 누를 때 발생하는 이벤트

 

제스처 이벤트 

-터치 이벤트 중에서 일정 패턴을 만들어 내는 이벤트 

 

포커스

-뷰마다순서대로 주어지는 포커스 

 

화면 방향 변경 이벤트 (액티비티 생명주기때 한번 해보았다) 

-화면의 방향이 가로/세로로 바뀜에 따리 발생하는 이벤트 

 


내용출처 : cafe.naver.com/sunschool/4394  혼자 이해하기도 어렵고 해서 정리 잘한거 같아서 참조함 

 

일반적인 터치 이벤트는 down - move -up 단계를 거치면서 사용자의 동작을 감지할 수 있다. 이런 사용자의 조합된 모션 (제스쳐)를 쉽게 판별할 수 있도록 안드로이드는 GestureDetector 인터페이스를 제공함 

 

GestureDetector 는 두가지의 Listener를 가지고 있는데 

 

interface GestureDetector.OnDoubleTapListener//두번 터치했을때

interface GestureDetector.OnDgetGestureListener // 일반적인 제스처      

하지만 위 두가지 다 가지고 있는 클래스가 GestureDetector.SimpleOnGestureListener 이다.

이 클래스를 상속 받으면 모든 제스처 다 사용할 수 있다  SImpleGestureListener());

사용법 : 

GestureDetector gestureDetector = new Gesture(this,  new  SImpleGestureListener());

gestureDetector.onTouchEvent(event);

 

오늘은 제스처를 통해 처리할 수 있는 이벤트를 먼저 배워볼것이다 .

일단 메소드는 아래와 같이 있다 

 case 1: 아주 살짝 터치하게 되면
 onDown
 onSingleTapUp     <- 30-60ms 후에 손이 떨어지면 발생
 onSingleTabConfirmed <- onDown 이벤트 발생후 300ms 안에 onDown 이벤트가 다
 시 발생하지 않을때 발생
 
case 2: 살짝 터치하게 되면
 onDown
 onShowPress  <- case1보다 조금 길게, 90-100ms 정도 터치되면 발생
 onSingleTapUp <- 172ms 이후에 손을 떼면 발생
 onSingleTabConfirmed <- onDown 이벤트 발생후 300ms 안에 onDown 이벤트가 다
시 발생하지 않을때 발생
 
case 3: 약간 길게 터치 되면
 onDown
 onShowPress <- 100ms 정도 터치되면 발생
 onSingleTapUp <- 300ms 이후 손을 떼게 되면 onSingleTabConfirmed는 발생하자
  100ms 정도 터치되면 발생
 
 않는다.
 case 4: 아주 길게 터치 되면
 onDown
 onShowPress <- looms 정도 터치되면 발생
 onLongPress <- 590-600ms 정도에 발생. 이때 onSingleTabUp은 발생하지 않는
 다.
  
 case 5: 두번 터치 하게 되면
 onDown
 onSingleTabUp 
 onDoubieTab  <- onSingieTabConfirmed가 발생하기 전에 다시 onDown 이벤트가 들
 어오게 되면 발생
 onDown         <- onDoubleTab 이벤트보다 빨리 들어올 수 도 있지만 일반적으로 늦게
 들어온다.
 
 
case 6: 두번 터치하게 되면
 onDown
 onSingleTapUp
 onDoubleTapEvent <- onSingleTapConfirmed가 발생하기전에 다시 onDown 이벤트
 가 들어오게 되면 발생
onDown <- 이건 onDoubleTap보다 먼저 들어올수도 늦게 들어올 수도 있다. 
onSingleTapUp <- 첫번째 onDoubleTapEvent는 ACTION_DOWN , 이것은ACTION_UP
onDoubleTap 과 onDoubleTapEvent와의 차이는 DOWN,MOVE,UP 이벤트까지 모두 캐치된다는 점이다 .

case 7: 스크롤
 onDown
 onScro11 <- 최소 30ms 이후부터 onScro11 이벤트가 발생할 수 있으며. 플링시키지 않고
 살며시 손을 떼면 끝까지 onScroll 이벤트가 연속으로 발생한다.
 
 case7: 플링
 onDown
 onScroll
 onFling <-스크롤과비슷하지만마지막에손가락을약간튕기게되면플링으로인식된 
 다.

위의 메소드를 활용한 코드 예시  (XML 생략 ) 

public class MainActivity extends AppCompatActivity {

    TextView textView;
    GestureDetector gestureDetector;
    ScrollView scrollView;
    final int SWIPE_MIN_DISTANCE = 120; //SWIPE을 인식하는 가장 작은 거리
    final int SWIPE_VALOCITY = 2000; //내가 지정하는 임의의 속도
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        View Layout1 = findViewById(R.id.layout1);
        View Layout2 = findViewById(R.id.layout2);
        scrollView = findViewById(R.id.scrollView);
        textView = findViewById(R.id.textView);

        Layout1.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int action = event.getAction();
                float x = event.getX();
                float y = event.getY();

                if (action == MotionEvent.ACTION_DOWN) {
                    textView.append("손가락 눌림 : " + x + "," + y + "\n");
                } else if (action == MotionEvent.ACTION_MOVE) {
                    textView.append("손가락 이동 : " + x + "," + y + "\n");
                } else if (action == MotionEvent.ACTION_UP) {
                    textView.append("손가락 땜 : " + x + "," + y + "\n");
                }
                scrollView.fullScroll(ScrollView.FOCUS_DOWN);
				// 위쪽 블럭의 좌표값을 불러오는 코드 

                return false;
            }
        });

        Layout2.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                gestureDetector.onTouchEvent(event);
                scrollView.fullScroll(ScrollView.FOCUS_DOWN);


                return false;
            }
        });
			
            //직접적인 메소드 활용 예시
        gestureDetector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
            @Override
            public boolean onDown(MotionEvent e) {
                textView.append("onDown 호출됨 "+ "\n");
                return false;
            }

            @Override
            public void onShowPress(MotionEvent e) {
                textView.append("onShowPress 호출됨 "+ "\n");
            }

            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                textView.append("onSingleTapUp 호출됨 "+ "\n");
                return false;
            }

            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                textView.append("onScroll 호출됨 "+ "\n");
                return false;
            }

            @Override
            public void onLongPress(MotionEvent e) {
                textView.append("onLongPress 호출됨 "+ "\n");
            }

            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                //textView.append("onFling 호출됨 "+ "\n");
                if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_VALOCITY){
                    Toast.makeText(getApplicationContext(), "LEFT SWIPE" , Toast.LENGTH_LONG).show();
                }else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_VALOCITY){
                    Toast.makeText(getApplicationContext(), "RIGHT SWIPE" , Toast.LENGTH_LONG).show();
                }else if (e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_VALOCITY){
                    Toast.makeText(getApplicationContext(), "UP SWIPE" , Toast.LENGTH_LONG).show();
                }else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_VALOCITY){
                    Toast.makeText(getApplicationContext(), "DOWN SWIPE" , Toast.LENGTH_LONG).show();
                }
                return false;
            }
        });

    }
}

이렇게 실행 하게 되면 아래의 사진과 같이 이벤트 처리시 확인해볼수 있다 .

 

파란블럭 터치 이동 땜 
노란블럭 스크롤후 필링화면

위처럼 작동되는것을 볼수 있는데 사실 일반적인 어플리케이션에서는 활용도가 낮지만 게임과 같은 곳에서 활용 많이 한다 

728x90
반응형