몰?.루();
안드로이드 scrollView scrollY 제대로 안 먹힐 때 (doOnLayout) 본문
제가 원한 것은 SubActivity를 띄웠을 때 바로 스크롤뷰가 특정 scrollY만큼 이동한 상태에서 화면이 보여지는 것이었습니다.
원했던 그림
실패한 코드 1 - onCreate나 onResume에 setScrollY 넣어보기
package com.example.test
import android.os.Bundle
import android.widget.ScrollView
import androidx.appcompat.app.AppCompatActivity
class SubActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sub)
}
override fun onResume() {
super.onResume()
val scrollView = findViewById<ScrollView>(R.id.scrollView)
scrollView.scrollY = 10000
}
}
onResume에 scrollView.scrollY = 10000
을 넣어봤지만 전혀 쓸모 없었습니다.
당연히 onCreate나 onStart에 넣어도 효과가 없었습니다.
실패한 코드 2 - .post 사용하기
package com.example.test
import android.os.Bundle
import android.widget.ScrollView
import androidx.appcompat.app.AppCompatActivity
class SubActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sub)
val scrollView = findViewById<ScrollView>(R.id.scrollView)
scrollView.post { scrollView.scrollY = 10000 }
}
}
이번엔 스택오버플로우에서 추천한 방식인 scrollView.post { scrollView.scrollY = 10000 }
을 사용하였습니다.
멀쩡하게 잘 동작하는 것 같지만 사실 아닙니다.
버튼을 클릭하면 서브 액티비티가 뿅 하고 나타나는 게 아니라 스스륵 올라오는데 이때 자세히 보면 스크롤뷰가 순간적으로 스크롤 위치를 변경하는 게 보입니다.
서브 액티비티가 등장할 때 올라오는 애니메이션을 제거하면 훨씬 더 잘 보입니다.
저는 사용자가 스크롤이 바뀌는 걸 눈치채면 안 되는 상황이었기 때문에 post를 사용하는 방식은 쓸 수 없었습니다.
참고로 View.post는 uithread의 큐에 작업을 추가하는 함수입니다. 따라서 ui 작업이 모두 끝난 후, 제가 코드로 넣은 setScrollY가 발동됩니다. 그렇기 때문에 처음 스크롤뷰가 보일 때부터 스크롤이 최하단으로 내려간 상태에서 시작하는 게 아니라, 스크롤뷰 최상단인 상태에서 uithread가 일을 마치고 나서 스크롤을 아래로 내리기 때문에 이런 현상이 발생했습니다.
성공한 방법 - doOnLayout
사수님에게 물어봤더니 doOnLayout이라는 게 있다고 써보라고 하셨습니다.
package com.example.test
import android.os.Bundle
import android.widget.ScrollView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.doOnLayout
class SubActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sub)
val scrollView = findViewById<ScrollView>(R.id.scrollView)
scrollView.doOnLayout { it.scrollY = 10000 }
}
}
결과는 대성공이었습니다.
doOnLayout은 처음 들어봤는데 찾아보니까 해당 View가 레이아웃에 놓여지는 순간 작업을 수행하는 콜백함수였습니다.
덕분에 원하는 기능을 구현할 수 있었습니다.
'프로그래밍 > 안드로이드, 코틀린' 카테고리의 다른 글
옵저버 패턴으로 직접 LiveData 만들어보기 (0) | 2023.07.06 |
---|---|
안드로이드 모서리가 둥근 버튼을 만드는 아주 쉬운 방법 (Rounded Button) (0) | 2023.03.01 |
안드로이드 스튜디오 terminal git bash 한글 이상하게 지워지는 문제 (0) | 2023.02.23 |
[안드로이드 코틀린] 부모 액티비티에서 자식 프래그먼트 함수 호출하기 (0) | 2023.02.20 |
코틀린 확장 함수는 자바에서 어떻게 구현될까? (0) | 2023.02.16 |
Comments