2011-12-13 1 views
0

필자는 Activity에 ActionBar를 추가하기 시작한 이후로 왜 내 ViewGroup 구현이 오작동했는지 이해하려고 애 쓰고 있습니다.화면에 ActionBar가있을 때 내 ViewGroup이 잘못 칠하는 이유는 무엇입니까?

저는 뷰의 현재 너비와 높이와 관련된 비율에 따라 뷰 집합을 레이아웃하는 사용자 지정 ViewGroup이 있습니다. ViewGroup은 절대적인 레이아웃과 비슷한 레이아웃 알고리즘을 구현하지만, 절대 좌표 대신 ViewGroup의 너비와 높이를 기준으로 좌표를 사용합니다.

레이아웃의 onMeasure 단계는 거의 무시합니다. 그 이유는 자식보기에 크기가 무엇인지 알려주기 위해서입니다. 내 사용자 지정 뷰 그룹 적절하게 자신을 페인트하지 않는의 자식으로 설정되어

@Override 
protected void onLayout(boolean changed, int left, int top, int right, int bottom) 
{ 
    if (isInEditMode()) return; 

    int height = getHeight(); 
    int width = getWidth(); 

    for (int i = 0; i < getChildCount(); i++) 
    { 
     View child = getChildAt(i); 
     ImageCell cell = cells.get(i); 

     int l = (int)(cell.getX0() * width); 
     int t = (int)(height - (cell.getY1() * height)); 
     int r = (int)(cell.getX1() * width); 
     int b = (int)(height - (cell.getY0() * height)); 

     child.layout(l, t, r, b); 

     child.setBackgroundColor(0xFFFF0000); 
    } 
} 

불행히도 전망 :

onLayout는 다음과 같은 작업을 수행합니다. 이러한 뷰는 단순한 비트 맵 드로잉 뷰이지만 비트 맵에는 스케일링 및 변환이 적용될 수 있습니다. 내보기의 onDraw()는 같은 것을 작성 다음 : 내가 스케일링 및 표시 할 필요가 이미지의 규모와 번역을 기반으로 캔버스에 변환을 적용하는 매트릭스를 설정하고

@Override 
public void onDraw(Canvas canvas) 
{ 

    if (canvasMatrix == null) 
    { 
     canvasMatrix = new Matrix(); 
    } 

    canvasMatrix.reset(); 
    canvasMatrix.setScale(scaleX, scaleY); 
    canvasMatrix.postTranslate(getLeft() + translationX, getTop() + translationY); 
    canvas.setMatrix(canvasMatrix); 

    synchronized (renderBuffer) 
    { 
     /** 
     * We need to offset the renderBuffer, the scaling is done by the matrix 
     * on the canvas. 
     */ 

     canvas.drawBitmap(renderBuffer, offsetX, offsetY, null); 

    } 
} 

을 . 그런 다음 이미지는 지정된 x 및 y 오프셋을 사용하여 캔버스에 그려집니다.

비트 맵이 ActionBar 아래에 그려지고 화면 아래쪽에 페인트되지 않은 큰 여백이 남습니다. offsetY에 상수를 추가하면 비트 맵을 화면의 올바른 위치에 페인트 할 수 있습니다 (장치의 회전에 따라 다름). 그러나이 상수 요인을 어디에서 계산해야하는지 잘 모르겠습니다.

나는 안드로이드 그리기에 대해 거의 이해하지 못했습니다. Canvas가 화면상의 뷰의 위치에 상대적이라고 예상 했으므로 (0,0)에 페인트하면 페인트가 화면의 원점이 아닌 뷰의 원점에 표시됩니다.

Strange Painting Issue Example

그래서이 이미지는 내가보고있는 무슨의 예입니다. 하단의 빨간색 영역은 drawBitmap에 의해 그려지지 않은 자식 뷰의 일부입니다.

내가 여기 잘못 생각한 이유는 무엇입니까? 보기가 전체 화면이지만, ActionBar가 있으면 ActionBar의 크기를 포함하는 좌표가 제공되지 않으므로 그 아래에 그림이있는 것처럼 보입니다.

답변

1

문제점 : canvas.setMatrix (canvasMatrix);

이 메서드를 호출하면 Canvas에 적용된 전체 변형이 불투명 해집니다. 전체 창에 대해 하나의 캔버스가 있으므로, 오프셋에 적용된 변형을 ActionBar 높이로 제거합니다.

또한 뷰에서 항상 measure()를 호출해야합니다. 일부 의견은이 호출이 제대로 작동 할 것으로 기대합니다.

+0

고마워요, 로맹. 지금 코드를 다시 작성하여 원본 행렬을 제거하지 않고 기존 행렬에 적절한 축척과 변환을 추가합니다. 이것은 확실히 내 문제를 해결합니다. – Thorinside

+0

또한 지시 된대로 모든 하위 뷰에서 측정을 호출 할 것입니다. – Thorinside

+0

맞춤 레이아웃에 대해 더 알고 싶다면 주제에 관한이 이야기를보아야합니다. http://www.parleys.com/#id=2191&st=5 –

관련 문제