Canvas.drawBitmap использует последнее содержимое Bitmap для всех вызовов

Я пытаюсь сделать несколько страниц PDF в пользовательском представлении в Xamarin.

    public override void Draw( AG.Canvas canvas ) {
        base.Draw( canvas );
        if( !(Parent is AW.ScrollView p) || pdfRenderer == null )
            return;
        int topPage = pdfRenderer.PageCount * p.ScrollY / Height;
        while( topPage < pdfRenderer.PageCount && topPage * screenPageHeight < p.ScrollY + p.Height ) {
            using( var page = pdfRenderer.OpenPage( topPage ) ) {
                page.Render( bitmap, null, null, PdfRenderMode.ForDisplay );
                page.Close();
            }
            AG.Rect pageRect = new AG.Rect {
                Left = 0,
                Top = topPage * screenPageHeight,
                Right = Width,
                Bottom = (topPage + 1) * screenPageHeight,
            };
            canvas.DrawBitmap( bitmap, null, pageRect, null );
            topPage++;
        }
    }

Выходные данные рисуют страницу из последнего цикла, запущенного во всех pageRect. Я могу себе представить, почему это может произойти, но реальный вопрос заключается в том, как я могу исправить этот код, чтобы рисовать все страницы, не создавая отдельного растрового изображения для каждой страницы.

РЕДАКТИРОВАТЬ. Скриншоты отладчика прилагаются. (На холсте. Точка останова rawBitmap)

РЕДАКТИРОВАТЬ. Добавлен код Java. Ожидаемый: один красный и один зеленый прямоугольник. Наблюдалось: два зеленых ректа.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new TestView());
    }

    class TestView extends View {
        public TestView() {
            super(MainActivity.this);
        }

        Bitmap bmp = Bitmap.createBitmap(600, 200, Bitmap.Config.ARGB_8888);
        Paint paint = new Paint();

        void FillBitmap(int color) {
            Canvas canvas = new Canvas(bmp);
            canvas.drawColor(color);
        }

        protected void onDraw (Canvas canvas) {
            FillBitmap(Color.RED);
            canvas.drawBitmap(bmp, 60, 120, paint);
            FillBitmap(Color.GREEN);
            canvas.drawBitmap(bmp, 60, 440, paint);
        }

        protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {
            setMeasuredDimension(720, 720);
        }
    }
}

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

1 ответ

Дэвид и я полагаем, что это связано с использованием Canvas с объектами Drawable, загруженными из одного и того же ресурса. Растровое изображение является рисованным. Xamarin - это очень тонкий слой оберток над API, поэтому он вряд ли связан с Xamarin, а более специфичен для Android. Обратите внимание на этот раздел документации: Примечание. Каждый уникальный ресурс в вашем проекте может поддерживать только одно состояние, независимо от того, сколько различных объектов вы создаете для него. Например, если вы создаете экземпляры двух объектов Drawable из одного и того же ресурса изображения и изменяете свойство (например, альфа) для одного объекта, то это также влияет на другой. При работе с несколькими экземплярами ресурса изображения вместо непосредственного преобразования объекта Drawable вы должны выполнить анимацию анимации. - https://developer.android.com/guide/topics/graphics/drawables- https://developer.android.com/reference/android/graphics/Canvas Итак, наиболее вероятной причиной является то, что вы создаете растровые экземпляры с того же ресурса (PDF). Я не вижу этого в вашем фрагменте кода для подтверждения, но это наиболее вероятная причина. Это также может быть связано с неоднократным использованием одного и того же экземпляра растрового изображения, а не нескольких отдельных экземпляров растрового изображения, но я не вижу этого и из фрагмента. Это может быть менее вероятно, чем причина, чем ранее упомянутые проблемы с Drawables на холсте. Проверьте, поможет ли анимация движения в вашем сценарии.

Обратите внимание, что могут быть более упрощенные способы представления PDF. Android (и Xamarin.Andriod) имеют API для PdfRenderer. Документация Android для этого находится здесь: https://developer.android.com/reference/android/graphics/pdf/PdfRenderer Xamarin.Android, и у нас есть документы API для оболочки Xamarin здесь: https://developer.xamarin.com/api/type/Android.Graphics.Pdf.PdfRenderer/ качестве альтернативы вы также можете установить pdf в качестве источника для WebView в Xamarin.Android или Xamarin.Forms, установив для свойства Source значение pdf в Xamarin.Forms.WebView или вызывая LoadUrl из экземпляра Android.Webkit.WebView.

Другие вопросы по тегам