일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- recyclerView 클릭이벤트
- fragment에서 context사용
- 녹음기
- LV1
- 임시저장하기
- bronze4
- bottom-up
- Silver5
- 다크모드제한
- Kotlin
- RETROFIT
- LIS
- naver open api
- 프로그래머스
- Alert Dialog
- silver3
- Android
- 백준
- dp
- RecyclerView
- toLong()
- 테마변경
- Top-Down
- map
- gradle설정
- silver4
- bronze2
- 뷰클래스
- bronze3
- stack
Archives
- Today
- Total
유니 코드
[Android] 녹음기 만들기 with 코틀린(4) - 오디오 시각화(Custom Drawing) 본문
커스텀뷰를 정의해서 녹음된 음성을 시각화하였다. 음폭에 따라 drawLine을 이용해 그려준다.
커스텀 뷰에는 Canvas로 무엇을 그릴지 Paint로 어떻게 그릴지 설정해준다. ( custom drawing )
//Paint 생성(음성시각화)
private val amplitudePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = context.getColor(R.color.purple_500)
strokeWidth = LINE_WIDTH
strokeCap = Paint.Cap.ROUND
}
paint객체를 정의해주고 아래에서 라인을 그려준다.
onSizeChanged를 오버라이드 해서 그릴 라인의 사이즈가 변경되는 경우 너비와 높이를 가져와 재설정할 수 있다.
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
drawingWidth = w
drawingHeight = h
}
onDraw
실제 paint 객체를 사용하여 원하는 라인을 그린다. 진폭에 대한 배열을 이용해 하나씩 그려준다.
이때, 우측부터 그리기 위해서 우측 좌표를 가지고 있다가 하나씩 그리면서 LINE_SPACE만큼 빼주면서 그린다.
뷰영역에서 넘어가는 경우에는 return을 해서 더이상 그리지 않는다.
재생할 때는 뒤에서부터 보여줘야하기 때문에 takeLast를 사용하였다.
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas?: return
val centerY = drawingHeight / 2f
var offsetX = drawingWidth.toFloat()
drawingAmplitudes
.let{ amplitudes ->
if(isReplaying){
amplitudes.takeLast(replayingPosition)
} else{
amplitudes
}
}
.forEach { amplitude ->
val lineLength = amplitude / MAX_AMPLITUDE * drawingHeight * 0.8F
offsetX -= LINE_SPACE
if(offsetX <0) return@forEach
canvas.drawLine(
offsetX,
centerY - lineLength / 2F,
offsetX,
centerY + lineLength / 2F,
amplitudePaint
)
}
}
녹음을 시작하면 오디오 시각화를 실시간으로 하기위해 runnable 객체를 post해서 일정 인터벌 당 계속해서 호출하도록 설정하였다. 진폭값을 실시간으로 가져와서 현재 리스트의 가장 앞에 붙여서 순차적으로 그려질 수 있도록 하였다.
이때 리스트가 변경되면 invalidate()를 호출하여 뷰를 갱신해주어야 한다.
//Runnable : 반복해서 자신을 실행시키도록 요청(interface)
private val visualizeRepeatAction: Runnable = object : Runnable{
override fun run() {
if(!isReplaying) {
val currentAmplitude = onRequestCurrentAmplitude?.invoke() ?: 0
drawingAmplitudes = listOf(currentAmplitude) + drawingAmplitudes
}else{
replayingPosition++
}
invalidate()
handler?.postDelayed(this, ACTION_INTERVAL)
}
}
'오늘의 공부는?! > Android' 카테고리의 다른 글
[Android/Kotlin] 도서 리뷰 앱 - Naver 검색 API(도서) 사용하기 (0) | 2022.06.29 |
---|---|
[Android] 뷰 클래스 ( 화면 구성) (0) | 2022.03.19 |
[Android] Custom Drawing (0) | 2022.02.24 |
[Android] 녹음기 만들기 with 코틀린(3) - 녹음 기능 구현하기(MediaRecorder, MediaPlayer 사용) (0) | 2022.02.22 |
Comments