마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

뷰가 깜빡거립니다. 마지막 한 번만 갱신하고 싶어요.

0 추천
뷰를 하나 만들어서 캔버스를 삽입했습니다.

주 동작은 도형이나 선을 그리고 해당 정보를 동작마다 스택에 쌓고 있는데요

예를들어 10개의 도형을 그렸다면 10개의 정보가 스택에 쌓입니다.

그런후에 undo를 누르면 화면을 클리어한 다음에 10개중에 마지막 1개를 제외한 9개를 다시 그리는 형식인데 분명히 전부 그린 다음에 invalidate 하는데도 화면이 깜빡거리네요

clearCanvas() -> draw 9개 -> invalidate()

뷰의 Ondraw()에 디버깅을 찍어봐도 invaldate()를 호출한 시점에만 호출되는데 디버깅 하다보면 그전에 화면이 하얗게 한번 클리어되네요.

invalidate할때 한번만 화면이 그려져야 되는데 어딘가 두 번 그려집니다..

뷰랑 캔버스 구조상 OnDraw()타기 전에도 디버깅찍어볼 곳이나 화면이 클리어되는 경우가 있나요?

해당뷰에 있는 Ondraw()타지 않고도 뷰나캔버스가 갱신 될수 있는지 궁금합니다.
더듬이 (340 포인트) 님이 2017년 6월 15일 질문

1개의 답변

0 추천
drawing 코드 부분을 올리셔야 정확한 상황을 알 수 있을 것 같습니다.
익명사용자 님이 2017년 6월 15일 답변
원인은 찾았습니다.
clear() -> draw() (9개만) -> invalidate() -> onDraw() 이런 흐름인데

clear()함수의 removeView()가 문제였네요.


private void clear() {
        ViewGroup parent = (ViewGroup)getParent();
        int children = parent.getChildCount();
        for(int i = 0; i < children; i++)
        {
            if(parent.getChildAt(i) instanceof ViewObject || parent.getChildAt(i) instanceof ViewGroupObject){
                parent.removeView(parent.getChildAt(i));
            }
        }
    }


해당 removeView를 따라가보면 SDK안에 이렇게 정의되어 있습니다.
@Override
    public void removeView(View view) {
        if (removeViewInternal(view)) {
            requestLayout();
            invalidate(true);
        }
    }

이거 invalidate 패스할수 없을까요 ;
ViewGroup.java의

public void removeViewInLayout(View view) {
        removeViewInternal(view);
    }

를사용하니 해결될것처럼 하면서 간헐적으로 깜빡이네요
...