在不同的分辨率上缩放VectorDrawables

时间:2016-03-22 16:17:13

标签: android

背景

我目前正在创建一个带引脚的地图。对于标记和引脚,我们使用的是VectorDrawables。我们的问题是获得与地图相关的所有设备上的标记/引脚的理想比例。在多个设备上处理矢量缩放的最佳做法是什么?

注意:对于这个问题,我们只关注Lollipop或更多设备,因为我们计划更新到支持VectorDrawables的最新支持库。

图片: 为了证明这一点,我提供了一张接近理想尺寸的图片。我确实有另一张照片显示平板电脑的外观,但遗憾的是我此时只允许发布一个链接。

[1]从S6上看:这是一个理想的尺寸,但难以获得所有设备。

Map Marker/Pins on Phone

代码

决定叠加大小的大部分内容由标记代码及其关联的矢量文件处理,但如果需要,我会提供更多代码。

添加叠加层

@Override
protected void onDraw(Canvas canvas)
{
    // Draw backgrounds
    super.onDraw(canvas);

    //set up the color and the mode for the filtering function
    //        paint.setColorFilter(cf);

    // Draw overlays
    for (ImageOverlay overlay : this.overlayList)
    {
        Matrix overlayMatrix = overlay.getTranslationMatrix();

        if (overlay.getIsScalable())
        {
            overlayMatrix.postConcat(getImageMatrix());
        }
        else
        {
            float[] vals = new float[]{0,0,0,0,0,0,0,0,0};
            getImageMatrix().getValues(vals);
            float scaleDx = overlay.getX() - (vals[Matrix.MSCALE_X]*overlay.getX());
            float scaleDy = overlay.getY() - (vals[Matrix.MSCALE_Y]*overlay.getY());
            overlayMatrix.postTranslate(vals[Matrix.MTRANS_X]-scaleDx, vals[Matrix.MTRANS_Y]-scaleDy);
        }

        canvas.drawBitmap(overlay.getImage(), overlayMatrix, paint);
    }
}

标记代码:

 /**
 * This method creates a bitmap for the mapMarker that we use to show where the customer is located on the map.
 * @return Returns a bitmap of the marker.
 */
private Bitmap buildMapMarker(){
    // Display the marker for that company
    Bitmap mapMarkerBitmap;
    if (Build.VERSION.SDK_INT >= 21){
        VectorDrawable mapMarkerVectorDrawable = (VectorDrawable) getResources().getDrawable(R.drawable.ic_place_red_24dp);
        mapMarkerBitmap = getOverlayBitmap(mapMarkerVectorDrawable, 79);
    } else {
        mapMarkerBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_place_red_24dp);
    }

    return mapMarkerBitmap;
}

/**
 * This method is used to obtain the overlay bitmap for devices that are >= API 21.
 * @param vectorDrawable Passed vectorDrawable to obtain info from.
 * @return
 */
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private Bitmap getOverlayBitmap(VectorDrawable vectorDrawable, int width) {
    Bitmap bitmap = Bitmap.createBitmap(width,
            width, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    vectorDrawable.draw(canvas);
    return bitmap;
}

标记矢量XML:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
    android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zm0,9.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"
    android:fillColor="#F44336"/>

尝试我做了:

      
  1. 使用矢量自身的dpi宽度/高度比,这导致标记在较高dpi设备上过大,例如s6和较小的设备,如Nexus 7
  2.   
  3. 为画布设置固定的宽度和高度,这导致低dpi设备上的标记比高dpi设备大得多。
  4.   
  5. 最初,我们为每个设备制作了单独的png,这是迄今为止最理想的解决方案,但我们希望尽可能以某种方式实现向量。
  6. 注意: 如果需要更多信息或代码来提供足够的响应,请告诉我。

0 个答案:

没有答案