Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy does my ViewGroup paint incorrectly when there is an ActionBar on the screen?
    primarykey
    data
    text
    <p>I've been spinning my wheels trying to understand why my ViewGroup implementation has been malfunctioning ever since I started trying to add an ActionBar to my Activity.</p> <p>I have a custom ViewGroup that lays out a set of views based on ratios related to the current width and height of the view. The ViewGroup implements a layout algorithm that is a little like absolute layout, but instead of absolute coordinates it takes coordinates relative to the width and height of the ViewGroup.</p> <p>I pretty much ignore the onMeasure pass of the layout, because I'm just going to tell the child views what their sizes will be.</p> <p>The onLayout does something like the following:</p> <pre><code>@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 &lt; 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); } } </code></pre> <p>Unfortunately the views that are set as children of my custom ViewGroup don't paint themselves properly. These views are simple bitmap drawing views, but the bitmaps may have a scaling and translation applied to them. My View onDraw() is written something like the following:</p> <pre><code>@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); } } </code></pre> <p>I am setting up a matrix that will apply a scaling and a translation to the canvas based on the scale and translation of the images that need to be displayed. Then the images are drawn on the canvas with a specified x and y offset.</p> <p>What seems to be happening is that the bitmap is painted up underneath the ActionBar, leaving a large margin of space at the bottom of the screen which is not painted. If I add a constant factor to offsetY, the bitmap can be made to paint in the correct location on the screen (depending on the rotation of the device). But I'm not sure where this constant factor should be calculated.</p> <p>I understand very little about Android drawing. I would have expected the Canvas to be relative to the view's location on the screen such that if I paint at (0,0) the paint would appear at the origin of the view, not the origin of the screen. </p> <p><img src="https://i.stack.imgur.com/B69Be.png" alt="Strange Painting Issue Example"></p> <p>So this image is an example of what I am seeing. The red area at the bottom is the part of the child view that is not painted by the drawBitmap.</p> <p>Any idea what I'm doing wrong here? Everything paints fine if the view is full screen, but with an ActionBar, I am not given coordinates that include the size of the ActionBar so I seem to be painting underneath it.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload