Есть ли способ не перерисовывать / аннулировать представление, а масштабироватьX и scaleY с макетом, подходящим для новой масштабированной ширины и высоты? - PullRequest
1 голос
/ 02 августа 2020

У меня customView, onDraw есть несколько путей создания чертежа 100px * 100px размера. По какой-то причине рисунок слишком сложен с разным размером LinearGradient для разных paints. Для простоты я рисую изображение стрелки, чтобы вы могли понять идею в качестве примера.

В моем customView он имеет следующие свойства:

  1. кликабельно, если щелкнуть цветной рисунок, он станет невидимым. (здесь размер макета важен, чтобы быть точным или почти точным без большого поля)

  2. изначально это 50% размер с setPivot(0,0) и расположен в координатах (a1, b1).

  3. Через 2 секунды он, наконец, будет иметь размер 100% с setPivot(0,0) и расположен в координатах (a2, b2).

I знаю, что с помощью анимации можно делать 2 и 3, однако я понятия не имею, как автоматически изменять размер макета (то есть интерактивную область) для аниматора для моего customView.

Я знаю, что перерисовка представления требует много памяти. Говорят, масштабирование и перевод только некоторая память и перерисовка активировать не будут. Следовательно, я пытаюсь использовать valueAnimator и setDuration для 2 секунд и ofInt(60) для 60 кадров в секунду. Я добавил AnimatorUpdateListener и обновил ожидаемый текущий коэффициент масштабирования (0.5f+(1-0.5f)*time_elapsed/2000, а также использовал

view.setScaleX(current_scaling_ratio);
view.setScaleY(current_scaling_ratio);

Однако я думаю, что существует проблема с установкой точной интерактивной области с помощью setScaleX или setScaleY. Пожалуйста, посмотрите следующее изображение в формате BMP. Я делаю вывод.

setScale подойдет только после того, как layout(l,t,r,b) вступит в силу и затем будет использовать этот новый размер макета для setScale, независимо от порядка вводимых вами кодов.

введите описание изображения здесь

Затем я пытаюсь проверить коды setScaleX и хочу понять, почему он может масштабировать вид / чертеж без его перерисовки. Однако я обнаружил следующее:

    public void setScaleX(float scaleX) {
        if (scaleX != getScaleX()) {
            scaleX = sanitizeFloatPropertyValue(scaleX, "scaleX");
            invalidateViewProperty(true, false);
            mRenderNode.setScaleX(scaleX);
            invalidateViewProperty(false, true);

            invalidateParentIfNeededAndWasQuickRejected();
            notifySubtreeAccessibilityStateChangedIfNeeded();
        }
    }
void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) {
        if (!isHardwareAccelerated()
                || !mRenderNode.isValid()
                || (mPrivateFlags & PFLAG_DRAW_ANIMATION) != 0) {
            if (invalidateParent) {
                invalidateParentCaches();
            }
            if (forceRedraw) {
                mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
            }
            invalidate(false);
        } else {
            damageInParent();
        }
    }
    protected void invalidateParentCaches() {
        if (mParent instanceof View) {
            ((View) mParent).mPrivateFlags |= PFLAG_INVALIDATED;
        }
    }

Однако я пытаюсь использовать parentView.mPrivateFlags |= PFLAG_INVALIDATED; Android Studio дает мне красный цвет на mPrivateFlags. Это параметр publi c, но я не знаю, почему не могу на него сослаться. Теперь я не могу продолжать. Я просто хочу сделать плавный вид, который изначально был уменьшен, и в течение 2 секунд он продолжал двигаться линейно и постепенно увеличивался до исходного размера. Кроме того, интерактивная область должна быть маленькой и достаточно точной, чтобы соответствовать виду вдоль траектории полета, поэтому, когда мне нужно определить, является ли нажатая точка прозрачной ARGB или нет, чтобы сделать вывод, является ли это эффективным щелчком.

...