Canvas.drawBitmap使用Bitmap的最后一个内容进行所有调用

时间:2018-06-12 16:16:01

标签: android xamarin canvas bitmap drawbitmap

我正在尝试在Xamarin的自定义视图中呈现多个PDF页面。

    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中最后一次循环运行的页面。我可以想象它为什么会发生,但真正的问题是如何修复此代码来绘制所有页面而不为每个页面创建单独的位图。

EDIT。附带调试器截图。 (在canvas.DrawBitmap断点处)

EDIT。添加了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);
        }
    }
}

enter image description here enter image description here

1 个答案:

答案 0 :(得分:0)

David和我相信这与使用画布和从同一资源加载的Drawable对象有关。位图是可绘制的。 Xamarin是API上非常薄的包装层,因此这与Xamarin不太可能相关,但更特定于Android。注意文档的这一部分: 注意:项目中的每个唯一资源都只能维护一个状态,无论您实例化了多少个不同的对象。例如,如果您从同一图像资源实例化两个Drawable对象并更改一个对象的属性(例如alpha),则它也会影响另一个对象。处理图像资源的多个实例时,应直接执行补间动画,而不是直接转换Drawable对象。 -https://developer.android.com/guide/topics/graphics/drawables -https://developer.android.com/reference/android/graphics/Canvas 因此,最可能的原因是您正在使用相同的资源(pdf)创建位图实例。我无法在您的代码段中确认这一点,但这是最可能的原因。 这也可能与重复使用相同的位图实例有关,而不是与多个单独的位图实例有关,但我也无法从代码段中看到这一点。与前面提到的“画布上可绘制对象”问题相比,它可能不太可能是原因。检查补间动画是否对您的场景有帮助。

但是请注意,可能存在更多简化的方法来显示PDF。 Android(和Xamarin.Andriod)具有用于PdfRenderer的API。 Android的相关文档在这里:https://developer.android.com/reference/android/graphics/pdf/PdfRenderer Xamarin.Android,此处有Xamarin包装器的API文档:https://developer.xamarin.com/api/type/Android.Graphics.Pdf.PdfRenderer/ 或者,您还可以通过在Xamarin.Forms.WebView中将Source属性设置为pdf或通过从Android.Webkit.WebView实例调用LoadUrl来将pdf设置为Xamarin.Android或Xamarin.Forms中WebView的源。