Почему моя ViewGroup рисует неправильно, когда на экране есть панель действий? - PullRequest
0 голосов
/ 14 декабря 2011

Я крутил свои колеса, пытаясь понять, почему моя реализация ViewGroup работала некорректно с тех пор, как я начал пытаться добавить ActionBar в свою активность.

У меня есть пользовательская 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 не рисуют себя должным образом.Эти виды являются простыми видами растрового изображения, но к ним могут применяться масштабирование и перевод.My View 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.

Кажется, что происходит то, что растровое изображение раскрашивается под панелью действий, оставляя большой запас пространства в нижней части экрана.который не окрашен.Если я добавлю постоянный коэффициент к offsetY, растровое изображение можно будет нарисовать в правильном месте на экране (в зависимости от поворота устройства).Но я не уверен, где этот постоянный коэффициент должен быть рассчитан.

Я очень мало понимаю о рисовании Android.Я ожидал, что Canvas будет относительно местоположения вида на экране, так что, если я буду рисовать в точке (0,0), краска появится в начале представления, а не в начале экрана.

Strange Painting Issue Example

Так что это изображение является примером того, что я вижу.Красная область внизу - это часть дочернего представления, которая не нарисована drawBitmap.

Есть идеи, что я здесь не так делаю?Все выглядит хорошо, если представление полноэкранное, но с ActionBar мне не дают координаты, которые включают размер ActionBar, поэтому я, кажется, рисую под ним.

1 Ответ

1 голос
/ 14 декабря 2011

Ваша проблема здесь: canvas.setMatrix (canvasMatrix);

Вызывая этот метод, вы уничтожаете все преобразования, примененные к Canvas. Для всего окна существует один холст, поэтому вы удаляете преобразование, примененное к смещению на высоту ActionBar.

Вы также должны всегда вызывать measure () для Views. Некоторые Представления ожидают, что этот вызов будет работать должным образом.

...