Запретить перерисовку градиента во время анимации

#android #android-layout #drawable

#Android #android-макет #можно рисовать

Вопрос:

Я установил градиентный рисунок в качестве фона. При выполнении некоторой 3D-транзакции (особенно по оси Y) GradientDrawable перерисовывает сам себя, и famerate не очень хорош.

  • Я не могу кэшировать представление, в котором рисунок задан в качестве фона, потому что я хочу, чтобы другие представления поверх этого анимировались.
  • Я не могу поместить другое представление только для фона и кэшировать это представление, потому что тогда это представление, отображаемое только в полноэкранном режиме, вызовет те же проблемы.
  • Я не могу использовать windowsDecorator для фона.

Итак, я хочу, чтобы это был способ остановить GradientDrawable, чтобы попытаться перерисовать себя во время анимации. Я думаю jumpToCurrentState() , что делает то, что я хочу, но я хочу, чтобы это работало на уровне API> = 8 и jumpToCurrentState() только для уровня API> = 11. Также я хотел бы знать, что jumpToCurrentState делает именно для переноса его в API lvl 8, но не могу найти функцию нигде в drawable(источник не выпущен?)

Итак, есть ли какой-нибудь способ кэшировать сам объект рисования, а не представление, содержащее этот объект рисования ?.

Последним средством будет не рисовать фон во время анимации, но я действительно очень хочу этого избежать.

Комментарии:

1. вы пробовали расширять GradientDrawable и откладывать рисование с помощью Drawable. Callback.scheduleDrawable(…), никогда не использовал его сам, но он может сработать здесь

2. что ж, я попробую это сейчас. scheduleDrawable блокирует отрисовку для перевода в новое состояние, пока она не сработает?

3. возможно, проигнорируйте рисование и введите свою собственную логику, установите when = 0 … если я правильно понимаю…

4. хорошо, я закончил созданием кэша для чертежей, я опубликую свой ответ, когда он будет завершен

Ответ №1:

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

Это значительно повышает скорость анимации.

   public class PGradientDrawable extends GradientDrawable {

    private int firstColor;
    private int secondColor;
    private Paint cachePaint = new Paint();
    private Canvas cacheCanvas = new Canvas();
    private Bitmap bitmap;

    public PGradientDrawable(Orientation angle, int[] intarray) {
        super(angle, intarray);
        firstColor = intarray[0];
        secondColor = intarray[1];
    }

    public boolean isBackground = false;
    boolean firstTime = true;

    public void buildCache(int width, int height) {
        if (bitmap != null)
            bitmap.recycle();
        try {
            bitmap = Bitmap
                    .createBitmap(width, height, Bitmap.Config.ARGB_8888);
            bitmap.setDensity(context.getResources().getDisplayMetrics().densityDpi);
            cacheCanvas.setBitmap(bitmap);
            // TODO shader must be what the GradientDrawable is,type
            // orientation..
            cachePaint.setShader(new LinearGradient(0, 0, width, height,
                    firstColor, secondColor, Shader.TileMode.CLAMP));
            cacheCanvas.drawPaint(cachePaint);

        } catch (OutOfMemoryError e) {
            // clear the bitmap force draw() to repaint
            bitmap = null;
        }

    }

    @Override
    public void draw(Canvas canvas) {
        if (bitmap != null) {
            // Draw the bitmap
            canvas.drawBitmap(bitmap, 0, 0, null);
            return;
        }
        super.draw(canvas);
    }

}