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.