【问题标题】:Drawing Canvas to Overlay绘制画布以叠加
【发布时间】:2013-03-04 15:19:58
【问题描述】:

我在 AsyncTaskdoInBackground 的画布上画了一个。绘图代码运行通过,一步步调试检查。 onPostExecute() 方法也被调用,也被检查过。然而,什么都没有被绘制?我可以确认绘图代码是正确的,因为之前在 Overlay 子类的 onDraw() 方法中运行了相同的逻辑。以下是来源:

import java.lang.ref.WeakReference;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.os.AsyncTask;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;

public class AsyncOverlayTask extends AsyncTask<DataVO, Void, Canvas> {

    private final Paint     mPathPaint;
    private final Paint     mPointPaint;
    private Path            path;
    private final MapView   mMapView;   
    private final Canvas    mCanvas;

    public AsyncOverlayTask(final MapView mapView, final Paint pathPaint, final Paint pointPaint) {

        mMapView = new WeakReference<MapView>( mapView ).get();
        mPathPaint = pathPaint;
        mPointPaint = pointPaint;
        mCanvas = new Canvas();     
    }

    @Override
    protected Canvas doInBackground(final DataVO... params) {
        Thread.currentThread().setName( "AsyncOverlayTask" );   
        final Canvas canvas = new Canvas();
        final Bitmap bitmap = Bitmap.createBitmap( mMapView.getWidth(), mMapView.getHeight(), Bitmap.Config.ARGB_8888 );
        canvas.setBitmap( bitmap );
        canvas.drawColor( Color.TRANSPARENT );
        GeoPoint previousGeoPoint = null;
        GeoPoint geoPoint = null;
        final Path path = new Path();
        Projection projection;
        // at least 2 elements in aData
        if ( ( params != null ) && ( params.length > 0 ) ) {
            for ( final DataVO dataVo : params ) {
                if ( dataVo.getLatitude().replace( ".", "" ).length() > 8 ) {
                    geoPoint = new GeoPoint( Integer.valueOf( dataVo.getLatitude().replace( ".", "" ).substring( 0, 8 ) ), Integer.valueOf( dataVo
                            .getLongitude().replace( ".", "" ).substring( 0, 7 ) ) );
                } else {
                    geoPoint = new GeoPoint( Integer.valueOf( dataVo.getLatitude().replace( ".", "" ) ), Integer.valueOf( dataVo.getLongitude()
                            .replace( ".", "" ) ) );
                }
                // project point
                projection = mMapView.getProjection();
                Point projectedPoint = new Point();
                projectedPoint = projection.toPixels( geoPoint, projectedPoint );
                // draw point
                canvas.drawCircle( projectedPoint.x, projectedPoint.y, 7, mPointPaint );
                if ( previousGeoPoint != null ) {
                    final Point prevPoint = new Point();
                    projection.toPixels( previousGeoPoint, prevPoint );
                    // if((projectedPoint.x != prevPoint.x) &&
                    // (projectedPoint.y != projectedPoint.y)) {
                    path.moveTo( projectedPoint.x, projectedPoint.y );
                    path.lineTo( prevPoint.x, prevPoint.y );
                    canvas.drawPath( path, mPathPaint );
                    // }
                } else {
                    path.moveTo( projectedPoint.x, projectedPoint.y );
                }
                previousGeoPoint = geoPoint;
            }

        }
        return canvas;

    }

    @Override
    protected void onPostExecute(final Canvas canvas) {
        if ( ( mMapView != null ) && ( canvas != null ) ) {
            final DataOverlay dataOverlay = new DataOverlay();
            dataOverlay.draw( canvas, mMapView, false );
            if ( mMapView != null ) {
                mMapView.getOverlays().add( ( dataOverlay ) );
                mMapView.invalidate();
            }
        }
    }

    private class DataOverlay extends Overlay {

        @Override
        public void draw(final Canvas canvas, final MapView mapView, final boolean shadow) {
            super.draw( canvas, mapView, shadow );
        }
    }
}

【问题讨论】:

  • 我有个线索。 mMapview.getWidth() 和 getHeight() 都返回 -1...

标签: android asynchronous maps overlay task


【解决方案1】:

您使用Canvas 绘制的所有内容实际上都会绘制到您在Canvas 上设置的Bitmap 上。您使用的 Bitmap 仅在 doInBackground() 中引用,其他任何地方都没有。您的叠加层需要做的是绘制位图:

@Override
protected Bitmap doInBackground(final DataVO... params) {
    return bitmap;
}

@Override
protected void onPostExecute(final Canvas canvas) {
    // ...
    final DataOverlay dataOverlay = new DataOverlay(bitmap);
    // ...
}

private class DataOverlay extends Overlay {
    private final Bitmap mBitmap;

    DataOverlay(Bitmap b) { mBitmap = b; }

    @Override
    public void draw(final Canvas canvas, final MapView mapView, final boolean shadow) {
        canvas.drawBitmap(b, 0.0f, 0.0f, null);
    }
}

【讨论】:

  • 听起来很合理。正要试一试。剩下的问题是 MapView.getWidth() 和 MapView.getHeight() 总是返回 0.0,即使 MapView 已实例化。我在某处读到,只有在调用 MapViews onDraw() 方法时/之后才能获得正确的值。但是,我很想扩展 MapView 只是为了接收这些值。有人知道更好的方法吗?
  • 您需要等到第一个布局之后才能获得合适的宽度和高度。为此,您可以使用 View.getViewTreeObserver()。
  • 好吧,我在第一个布局之后实例化这个类年龄。它就像:onCreate(绑定视图)-> onStart -> onResume(添加 MyLocationOverlay 和其他东西)-> 做更多的东西-> AsyncOverlayTask.execute()
  • 可以画矢量图吗?
猜你喜欢
  • 2021-05-03
  • 1970-01-01
  • 2016-02-29
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 2018-01-06
  • 2012-05-04
相关资源
最近更新 更多