我有一个应用程序,我使用适配器类在3x3 GridView中显示九个视图。在GridView的单元格中包含的九个视图中的每个视图中,我使用Canvas和Paint对象来显示二维线图形;随后通过调用每个视图的invalidate()方法修改并重新显示这些线图形。
在Adapter类的重写getView()方法中创建视图时,所有九个视图中的线图形都能正确显示,但是当我尝试修改然后再重新显示线图形时,所有视图都会成功刷新< em>除了,用于网格左上角的第一个视图,它继续显示原始线条图。我已经通过我的代码来确定第一个视图肯定是无效的,它是,所以我很困惑为什么在第一个视图上调用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);
}
}
任何人都知道为什么第一个视图没有被重绘?
答案 0 :(得分:2)
好的,最后得到了这一点 - 事实证明,TestCanvas类中的getView方法对于testCanvass [0]被称为两次,但对于所有其他元素只有一次。我天真地假设Adapter类的getView方法将为数组中的每个元素调用一次,但是this post确认getView可能被多次调用,因为各种不明原因,对于没有经验的人来说不太明显像我这样的Android开发者。一旦我理解了这一点,我就可以很容易地添加下面的逻辑来检查testCanvass [position]是否为null,然后在TestCanvasAdapter.getView方法中为它分配了视图引用,从而解决了这个问题。
// 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不厌其烦地回复此查询。
答案 1 :(得分:0)
如果调用第一个视图的onDraw()方法,则无效工作。如果视图不与剪切矩形相交,则不会调用onDraw()。您可以通过打开Dev Tools应用程序(在模拟器上,但也可以将其安装在手机上)进行验证,然后在开发设置屏幕中,启用“显示屏幕更新”。它将闪烁屏幕无效/重绘的区域。