안드로이드

Android Exoplayer 제스쳐 기능 추가

2020. 5. 8. 16:28

네이버 TV 앱을 보면 영상 재생 시 화면 중앙을 기준으로 왼쪽 화면에서 위아래로 드래그 하면 밝기가 조절되고 오른쪽 화면에서 위아래로 드래그 하면 미디어 볼륨이 조절되는 기능이 있다.

 

꼭 필요한 기능은 아니지만 있으면 편리한 기능이라고 생각해 이를 구현해보기로 하였다.

 

가장 먼저 터치 이벤트를 받아야 한다. 이벤트를 받아야 볼륨을 조절하든 할테니까.

playerView.setOnTouchListener { _, motionEvent ->

    when (motionEvent.actionMasked) {
        MotionEvent.ACTION_DOWN -> {
            true
        }

        MotionEvent.ACTION_UP -> {
            true
        }

        MotionEvent.ACTION_MOVE -> {
            true
        }
        else -> super.onTouchEvent(motionEvent)
    }
}

위와 같이 playerView에 setOnTouchListener를 통해 터치 이벤트를 받아왔다.

 

ACTION_DOWN 이벤트는 화면에 터치가 처음 눌렸을 때 한 번 들어오는 이벤트다.

ACTION_UP 은 터치한 손가락을 화면에서 뗐을 때 한 번 들어온다.

ACTION_MOVE 는 화면에서 손가락이 터치한 채로 움직이면 (드래그) 좌표가 바뀔때마다 이벤트가 들어온다.

 

난 사용자가 처음 터치한 위치부터 계산해 일정 좌표만큼 움직였을 때 볼륨이나 밝기를 조절해야 하므로

ACTION_DOWN 이벤트에서 초기좌표를 저장하고 ACTION_MOVE 이벤트에서 현재 좌표가 초기 좌표에서 얼마나 멀어졌는지 계산해 상황에 맞는 작업을 하면 될 것이다.

 

최종 코드는 아래와 같다

playerView.setOnTouchListener { _, motionEvent ->

    when (motionEvent.actionMasked) {
        MotionEvent.ACTION_DOWN -> {
            if(isControlHidden) {
                playerView.showController()
                isControlHidden = false
            }
            else{
                playerView.hideController()
                isControlHidden = true
            }
            x = motionEvent.x  // 초기 좌표값 저장
            y = motionEvent.y
            isLeftGesture = x < (screenWidth / 2)  // 왼쪽 화면인지 오른쪽 화면인지 확인
            true
        }

        MotionEvent.ACTION_UP -> {
            true
        }

        MotionEvent.ACTION_MOVE -> {
            val x2: Double = motionEvent.x.toDouble()
            val y2: Double = motionEvent.y.toDouble()

            val diffX = (Math.floor(x2 - x)).toInt()  // 초기 좌표값에서 얼마나 멀어졌는지
            var diffY = (Math.floor(y2 - y)).toInt()

			// 초기 좌표값에서 70(임의의 수) 만큼 이동했을때
            if(Math.abs(diffY) > Math.abs(diffX) && Math.abs(diffY) >= 70) {
                if(isLeftGesture){  // 왼쪽 화면이면
                    brightness = if(y < y2) {  // 밝기 조절
                        (brightness - 0.1F)
                    } else {
                        (brightness + 0.1F)
                    }
                    if(brightness < 0) {
                        brightness = 0F
                    }
                    else if(brightness > 1.0) {
                        brightness = 1F
                    }
                    lp.screenBrightness = brightness
                    window.attributes = lp
                }
                else{  // 오른쪽 화면이면
                    if(y < y2) {
                        // 볼륨 조절
                        audioManager.adjustVolume(AudioManager.ADJUST_LOWER, AudioManager.FLAG_PLAY_SOUND)
                    }
                    else {
                        audioManager.adjustVolume(AudioManager.ADJUST_RAISE, AudioManager.FLAG_PLAY_SOUND)
                    }
                }
                y = y2.toFloat()  // 주기적으로 초기 좌표값을 변경해줌
            }
            true
        }
        else -> super.onTouchEvent(motionEvent)
    }
}

 

x와 y, isLeftGesture는 전역으로 선언해둔 변수이다.

 

5번째 줄부터 12번째 줄까지의 코드는 컨트롤러를 숨기고 표시하는 코드이다.

기본적으로 playerView의 터치 이벤트를 뺏어오는 것이므로 화면을 터치했을 때 컨트롤러가 숨겨지거나 보이지 않기 때문에 임의로 컨트롤러를 사라지게 해 주어야 한다.

 

이렇게 ExoPlayer에서 제스쳐를 통해 볼륨과 밝기를 제어해 보았다.

더 추가해볼만한 기능은 없을지 생각해 봐야겠다.