自从我开始尝试将ActionBar添加到我的Activity中以来,我一直在试图理解为什么我的ViewGroup实现出现故障。
我有一个自定义ViewGroup,它根据与视图当前宽度和高度相关的比率布局一组视图。 ViewGroup实现的布局算法有点像绝对布局,但它取代了绝对坐标,它采用相对于ViewGroup的宽度和高度的坐标。
我几乎忽略了布局的onMeasure传递,因为我只是想告诉孩子他们的尺寸是什么。
onLayout执行以下操作:
@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);
}
}
不幸的是,设置为我自定义ViewGroup的子视图的视图无法正确绘制自己。这些视图是简单的位图绘制视图,但位图可能会应用缩放和转换。我的视图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添加一个常数因子,可以使位图在屏幕上的正确位置绘制(取决于设备的旋转)。但我不确定应该在何处计算这个常数因子。
我对Android绘图知之甚少。我原本期望Canvas相对于屏幕上的视图位置,这样如果我在(0,0)绘画,绘画将出现在视图的原点,而不是屏幕的原点。
所以这张图片就是我所看到的一个例子。底部的红色区域是子视图中未由drawBitmap绘制的部分。
知道我在这里做错了什么吗?如果视图是全屏的,那么一切都很好,但是使用ActionBar,我没有给出包含ActionBar大小的坐标,所以我似乎在它下面绘画。
答案 0 :(得分:1)
你的问题在这里:canvas.setMatrix(canvasMatrix);
通过调用此方法,您可以破坏应用于Canvas的整个变换。整个窗口都有一个Canvas,因此您要删除应用于ActionBar高度偏移的变换。
您还应始终在Views上调用measure()。一些观点期望此调用正常工作。