2011-01-21 3 views
1

어댑터 클래스를 사용하여 3x3 GridView 내에 9 개의 뷰를 표시하는 응용 프로그램이 있습니다. GridView 셀에 포함 된 9 개의 뷰 각각에서 Canvas 및 Paint 객체를 사용하여 2 차원 선 그래픽을 표시합니다. 이러한 라인 그래픽은 각 뷰의 invalidate() 메소드를 호출하여 수정되고 다시 표시됩니다.뷰 배열에 대해 invalidate 메서드를 호출하면 첫 번째 뷰가 다시 그려지지 않습니다.

View가 Adapter 클래스의 재정의 된 getView() 메소드에서 생성 될 때 모든 9 개의 뷰의 라인 그래픽이 올바르게 표시되지만, 이후에 라인 그래픽을 수정 한 다음 다시 표시하려고하면 모든 뷰가 성공적으로 새로 고쳐집니다 의 경우을 제외하고 첫 번째보기는 그리드의 왼쪽 상단 모서리에 있으며, 원래 선 그리기를 계속 보여줍니다. 첫 번째보기가 확실히 무효화되고 있음을 확인하기 위해 코드를 단계별로 실행했습니다. 그래서 첫 번째보기에서 invalidate() 메서드를 호출해도 다시 그려지지 않습니다. 나머지 뷰 모두에 대해 동일한 호출을 수행하면 성공적으로 다시 그려집니다. 또한 뷰의 onDraw 메서드에 대한 호출을 기록 했으므로 첫 번째 뷰의 onDraw 메서드가 매번 호출되므로이 문제가 응용 프로그램 코드의 버그로 인해 발생하지 않았 음을 알 수 있습니다.

다음과 같이 수정하고 구 뷰를 갱신하는 코드는 다음과 같이

void updateViews(int parentTestCanvas) { 

    TestCanvasView testCanvas = testCanvass[parentTestCanvas]; 
    double[] parentGenome = testCanvas.getGenome(); 

    // Assign the parent genome to the testCanvass in the array 
    // The inherited genome will be subject to mutation in all cases except the first testCanvas 
    for(int testCanvasItem = 0; testCanvasItem < TestCanvasApp.geneCount; testCanvasItem++) { 

     testCanvas = testCanvass[testCanvasItem]; 
     testCanvas.setGenome(parentGenome); 

     // Invalidate the testCanvas view to force it to be redrawn using the new genome 
     testCanvas.invalidate(); 
    } 


} 

TestCanvasView 클래스의 onDraw는 방법은 다음과 같습니다

protected void onDraw(Canvas canvas) { 

    float xOrigin = getMeasuredWidth()/2; 
    float yOrigin = getMeasuredHeight()/2; 

    canvas.drawPaint(cellPaint); 

    canvas.translate(xOrigin, yOrigin); 
    drawBranch(canvas, linePaint, 0, 0, this.length, this.direction, this.xInc, this.yInc, this.scale); 
    Log.d("TestCanvasView", "Drawing testCanvas " + mCellIndex); 
} 

private void drawBranch(Canvas canvas, Paint linePaint, double startX, 
     double startY, double branchLen, int branchDir, double[] xInc, 
     double[] yInc, double scale) { 

    branchDir = (branchDir + 8) % 8; 

    double newX = startX + branchLen * xInc[branchDir]; 
    double newY = startY + branchLen * yInc[branchDir]; 

    canvas.drawLine((float) (startX/scale), (float) (-startY/scale), 
      (float) (newX/scale), (float) (-newY/scale), linePaint); 

    if (branchLen > 1) { 
     drawBranch(canvas, linePaint, newX, newY, branchLen - 1, branchDir + 1, xInc, yInc, scale); 
     drawBranch(canvas, linePaint, newX, newY, branchLen - 1, branchDir - 1, xInc, yInc, scale); 
    } 

} 

누구가에 관해서는 어떤 아이디어를 가지고 왜 첫 번째보기가 다시 그려지지 않습니다?

답변

2

OK, 마침내이 부분을 살펴 보았습니다. TestCanvasAdapter 클래스의 getView 메소드가 으로 두 번 호출되었지만 testCanvass [0]에 대해으로 두 번 나타 났지만 다른 모든 요소에 대해서는 한 번만 나타났습니다. 순진하게도 Adapter 클래스의 getView 메소드가 배열의 각 요소에 대해 한 번만 호출되지만, this post은 나 같은 경험이 거의없는 안드로이드 개발자가 쉽게 볼 수없는 다양한 모호한 이유로 getView가 두 번 이상 호출 될 수 있음을 확인합니다. . 이것을 이해하고 나면 testCanvass [위치]가 문제를 해결 한 TestCanvasAdapter.getView 메소드 내에서 뷰 참조를 할당하기 전에 null이 아니 었는지 확인하기 위해 아래 논리를 쉽게 추가 할 수있었습니다.

  // Add the newly created TestCanvasView object to the array on the TestCanvasApp object 
     if (position >= 0 && position < TestCanvasApp.viewCount 
       && mTestCanvasApp.testCanvass[position] == null) { 
        mTestCanvasApp.testCanvass[position] = testCanvasView; 
     } 

이 쿼리에 답장하는 데 많은 어려움을 겪어 준 Romain Guy에게 많은 감사를드립니다.

+0

위치 0을 여러 번 호출해도 동일한보기가 반드시 재생되는 것은 아닙니다. 이는 상태 저장 목록 항목에 대한 캐싱 논리를 복잡하게 만들 수 있습니다. –

0

첫 번째보기의 onDraw() 메소드가 호출 된 경우 무효화가 작동합니다. 뷰가 클리핑 사각형과 교차하지 않으면 onDraw()가 호출되지 않습니다. Dev Tools app (에뮬레이터에서는 전화기에 설치할 수도 있음)를 열고 개발 설정 화면에서 "화면 업데이트 표시"를 켭니다. 화면의 영역이 무효화되거나 다시 그려집니다.

+0

괜찮습니다. invalidate() 호출로보기 0을 포함하여 모든보기가 다시 그려지도록 설정했습니다. 문제의 진정한 원인은 updateViews 내에서 testCanvass [0] 즉, testCanvass [0]이 updateViews의 범위 내에서 성공적으로 수정 된 것처럼 보이지만 updateViews 메소드가 실행을 완료하고 종료되면 testCanvass [0]의 원래 내용이 신비하게 복원되어 testCanvass [0] ' 원래의 그리기 지침을 따르므로 라인 그래픽이 화면에서 변경되지 않습니다. – Paul

+0

이것은 testCanvass [0]에서만 발생합니다. updateViews가 완료된 후 testCanvass [] 배열 내의 다른 모든보기가 수정 된 상태로 유지됩니다.나는이 행동에 대해 완전히 당황 스럽다. Java (또는 Android Android 구현)는 배열의 0 번째 요소에 대한 참조를 다른 요소와 다른 방식으로 처리합니다 ?? – Paul

+0

아니요, 0 번째 요소는 다른 요소와 마찬가지로 처리됩니다. –