티스토리 뷰
Stack Overflow에 자주 검색, 등록되는 문제들과 제가 개발 중 찾아 본 문제들 중에서 나중에도 찾아 볼 것 같은 문제들을 정리하고 있습니다.
Stack Overflow에서 가장 먼저 확인하게 되는 가장 높은 점수를 받은 Solution과 현 시점에 도움이 될 수 있는 가장 최근에 업데이트(최소 점수 확보)된 Solution을 각각 정리하였습니다.
아래 word cloud를 통해 이번 포스팅의 주요 키워드를 미리 확인하세요.
Call removeView() on the child's parent first
'우선 child의 parent에서 removeView()를 호출하세요' 오류 수정하기
문제 내용
First a little background:
우선 배경 설명을 드리겠습니다.
I have a layout inside a scrollview. At first, when the user scrolls on the screen, the scrollview scrolls. However, after a certain amount of scroll, I was to disable the scroll on the scroll view the move the "scroll focus" onto a webview inside the child layout. This way, the scrollview sticks and all the scroll events go to the webview inside it.
저는 스크롤뷰 내부에 레이아웃이 있습니다. 사용자가 화면을 스크롤할 때, 일단 스크롤뷰가 스크롤됩니다. 그러나 일정 스크롤 양 이상이 되면, 스크롤뷰에서 스크롤을 비활성화하고, 자식 레이아웃 내부의 웹뷰로 "스크롤 포커스"를 이동하고 싶습니다. 이렇게 하면 스크롤뷰가 고정되고, 모든 스크롤 이벤트가 내부의 웹뷰로 전달됩니다.
So, for a solution, when the scroll threshold is reached, I remove the child layout from the scrollview and put it in scrollview's parent.(And make the scrollview invisible).
그래서 해결책으로는, 스크롤 임계값에 도달하면, 스크롤뷰에서 자식 레이아웃을 제거하고 스크롤뷰의 부모에 넣습니다. (그리고 스크롤뷰를 보이지 않게 만듭니다.)
// Remove the child view from the scroll view
scrollView.removeView(scrollChildLayout);
// Get scroll view out of the way
scrollView.setVisibility(View.GONE);
// Put the child view into scrollview's parent view
parentLayout.addView(scrollChildLayout);
General Idea: (-> means contains)
일반적인 아이디어: (->은 포함한다는 의미입니다)
Before: parentlayout -> scrollview -> scrollChildLayout
이전 상태 : parentlayout -> scrollview -> scrollChildLayout
After : parentLayout -> scrollChildLayout
이후 : parentLayout -> scrollChildLayout
The above code is giving me this exception:
위 코드는 다음 예외를 발생시킵니다:
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:1976)
at android.view.ViewGroup.addView(ViewGroup.java:1871)
at android.view.ViewGroup.addView(ViewGroup.java:1828)
at android.view.ViewGroup.addView(ViewGroup.java:1808)
Do you know what's going on? I am clearly calling removeView on the parent.
무슨 일이 일어나고 있는지 알고 계신가요? 분명히 부모의 removeView()를 호출하고 있는데요.
높은 점수를 받은 Solution
Solution:
해결책:
((ViewGroup)scrollChildLayout.getParent()).removeView(scrollChildLayout);
//scrollView.removeView(scrollChildLayout);
Use the child element to get a reference to the parent. Cast the parent to a ViewGroup so that you get access to the removeView method and use that.
부모 요소에 대한 참조를 얻기 위해 자식 요소를 사용하고, removeView 메서드에 액세스할 수 있도록 부모를 ViewGroup으로 캐스트합니다.
Thanks to @Dongshengcn for the solution
해결책에 대해 @Dongshengcn에게 감사드립니다.
가장 최근 달린 Solution
Kotlin Solution
코틀린 해결책
Kotlin simplifies parent casting with as?
, returning null if left side is null or cast fails.
Kotlin은 as?를 사용하여 부모 캐스팅을 간소화합니다. 만약 왼쪽에 있는 객체가 null이거나 캐스팅에 실패하면 null을 반환합니다.
(childView.parent as? ViewGroup)?.removeView(childView)
Kotlin Extension Solution
Kotlin 확장 함수를 이용한 해결책
If you want to simplify this even further, you can add this extension.
만약 더 간단하게 하고 싶다면, 이 확장 함수를 추가할 수 있습니다.
childView.removeSelf()
fun View?.removeSelf() {
this ?: return
val parentView = parent as? ViewGroup ?: return
parentView.removeView(this)
}
It will safely do nothing if this View is null, parent view is null, or parent view is not a ViewGroup
만약 이 View가 null이거나, 부모 View가 null인 경우 또는 부모 View가 ViewGroup이 아닌 경우, 안전하게 아무것도 수행하지 않습니다.
NOTE: If you also want safe removal of child views by parent, add this:
참고: 부모 뷰로 자식 뷰를 안전하게 제거하려면 다음을 추가하세요:
fun ViewGroup.removeViewSafe(toRemove: View) {
if (contains(toRemove)) removeView(toRemove)
}
출처 : https://stackoverflow.com/questions/6526874/call-removeview-on-the-childs-parent-first
'개발 > 안드로이드' 카테고리의 다른 글
Android WebView를 포함하는 앱에서 브라우저를 여는 대신 리다이렉션 처리하기 (0) | 2022.12.13 |
---|---|
Firebase에서 앱이 백그라운드에 있을 때 알림 처리 방법 (0) | 2022.12.12 |
안드로이드에서 서비스 실행 중인지 확인하기 (0) | 2022.12.12 |
WebView에 핀치 줌 ON/OFF 하기 (0) | 2022.12.12 |
'android.view.InflateException Error inflating class android.webkit.WebView' 오류 수정하기 (0) | 2022.12.12 |