답변:
François BOURLIEUX 와 Dalvik의 답변을 더 잘 이해하려면 Arpit Mathur 의이 멋진 뷰 수명주기 다이어그램을 살펴 보는 것이 좋습니다 .
TextView
. 나는 그들이을 그리려는 어쩌면 그 생각 View
들이 레이아웃 관련 매개 변수를 변경하기 전에 마지막으로,하지만 우리는 다른 순서로 호출되는 이러한 호출 생각해 보면 정말 이해가되지 않습니다 (그들은 호출 invalidate()
직후 requestLayout()
에 TextView
게다가). 어쩌면 StackOverflow :)에 대한 또 다른 질문이 필요합니까?
invalidate()
과 requestLayout()
)을 올바르게 이해하지 못한다고 생각합니다 . 이러한 방법의 목적은 View
어떤 종류의 무효화 가 발생 했는지 알려주는 것 입니다. View
이러한 메소드 중 하나를 호출 한 후 따라야 할 경로를 결정하는 것은 아닙니다 . View
-lifecycle-path 선택의 논리 는 자신을 호출 할 적절한 방법을 선택하는 것입니다. 크기 변경과 관련 requestLayout()
이있는 경우 (호출해야 함) 크기를 변경하지 않은 상태에서 시각적 변경 만있는 경우을 호출해야합니다 invalidate()
.
View
어떤 방법으로, 예를 들어, 당신은 현재의 수LayoutParams
(A)의 View
당신은 그들을 수정할 수 있지만 NOT 중 전화 requestLayout
또는 setLayoutParams
(호출하는 requestLayout
다음 호출 할 수 있습니다, 내부적으로) invalidate()
당신이 원하는만큼, 그리고 이 View
때문에 크기를 변경하지 않습니다, 측정 레이아웃 과정을 거쳐야하지 않습니다. 당신이 말하지 않으면 View
그 크기가 (A로 변경하는 requestLayout
메소드 호출), 다음은 View
그것을하지 않았다 가정 것이고, onMeasure
및 onLayout
호출되지 않습니다.
invalidate()
invalidate()
뷰 다시 그리기를 예약하려는 경우 호출 이 수행됩니다. 그것은 발생합니다 onDraw
(그러나 즉시, 곧) 결국 호출되는. 사용자 정의보기에서 호출하는 예는 텍스트 또는 배경색 속성이 변경된 경우입니다.
뷰가 다시 그려 지지만 크기는 변경되지 않습니다.
requestLayout()
보기에 대한 내용이 변경되어 크기에 영향을 줄 경우을 호출해야합니다 requestLayout()
. 이 트리거 onMeasure
와 onLayout
부모 뷰 라인 업 방식이 뷰를 제외한 모든 아닙니다.
호출 requestLayout()
은 (허용 된 답변의 다이어그램이 의미하는 것과는 달리) 결과를 보장하지 않으므로onDraw
일반적으로와 결합됩니다 invalidate()
.
invalidate();
requestLayout();
예를 들어 맞춤 라벨의 텍스트 속성이 변경된 경우입니다. 라벨 크기가 변경되므로 다시 측정하고 다시 그려야합니다.
forceLayout()
있을 때 requestLayout()
부모 뷰 그룹에서 호출되는, 그렇지 재 측정을하고 아이 뷰 레이아웃 작업에 필요한 필요하지 않습니다. 그러나 재 측정 및 중계에 아동을 포함시켜야하는 경우 아동에게 전화를 걸 수 있습니다 forceLayout()
. 직계 부모 forceLayout()
와 함께 발생하는 경우에만 아동에게 적용됩니다 requestLayout()
. 뷰 트리를 forceLayout()
트리거하지 않기 때문에 자체 호출 은 효과가 없습니다 requestLayout()
.
에 대한 자세한 설명은 이 Q & A 를 읽으십시오 forceLayout()
.
View
소스 코드requestLayout()
를 걸 수 있습니다 invalidate()
. 어느 쪽도 레이아웃을 만들거나 즉시 그릴 수 없습니다. 오히려 그들은 결국 릴레이 아웃 및 다시 그리기 결과 플래그를 설정합니다.
여기에 몇 가지 응답이 있습니다. http://developer.android.com/guide/topics/ui/how-android-draws.html
나에게 전화를 걸면 invalidate()
뷰가 requestLayout()
새로 고쳐지고 전화를 걸면 뷰 가 새로 고쳐지고 화면 크기가 계산됩니다.
이 답변 은에 대해 정확하지 않습니다 forceLayout()
.
코드forceLayout()
에서 볼 수 있듯이 뷰는 "중계가 필요"로 표시되지만 해당 중계를 예약하거나 트리거하지는 않습니다. 향후 어느 시점에서보기의 부모가 다른 이유로 배치 될 때까지 릴레이 아웃이 발생하지 않습니다.
forceLayout()
and를 사용할 때 훨씬 더 큰 문제가 있습니다 requestLayout()
.
당신이 forceLayout()
보기에 전화했다고 가정 해 봅시다 . 이제 requestLayout()
해당 뷰의 자손을 호출 할 때 Android는 requestLayout()
해당 자손의 조상을 재귀 적으로 호출 합니다. 문제는 호출 한보 기에서 재귀를 중지한다는 것입니다 forceLayout()
. 따라서 requestLayout()
호출은 뷰 루트에 도달하지 않으므로 레이아웃 패스를 예약하지 않습니다. 뷰 계층 구조의 전체 하위 트리가 레이아웃을 기다리고 requestLayout()
있으며 해당 하위 트리의 뷰를 호출 해도 레이아웃이 발생하지 않습니다. 해당 requestLayout()
서브 트리 외부의 뷰만 호출 하면 철자가 깨집니다.
나는 구현을 고려할 것이다 forceLayout()
(그리고 그것이 어떻게 영향 requestLayout()
을 미치는지 깨달았 으므로 코드에서 그 기능을 사용해서는 안된다.
View
하고 문제를 직접 실행하고 디버깅하여 알아 냈습니다 .
forceLayout()
API 의 목적이 궁금 합니다. 실제로 레이아웃 패스를 강제하지는 않지만 에서 관찰되는onMeasure()
플래그 를 변경 하지만 명시 적 또는 명시 적 onMeasure()
호출이 없으면 호출되지 않습니다 . 즉, 와 쌍을 이루어야합니다 . 반면에 여전히 수행해야하는 경우 수행해야하는 이유는 무엇입니까? requestLayout()
View#measure()
forceLayout()
requestLayout()
forceLayout()
requestLayout()
requestLayout()
모든 일을 forceLayout()
합니다.
forceLayout
이 의미가 있습니다. 결국에는 이름이 매우 잘못 지정되고 문서화되었습니다.