2016-04-01 70 views
0

我已經寫在運行時產生一個谷歌地圖標記的自定義視圖,下面的代碼:定製視圖的一部分不在運行時渲染?

public class CustomMapMarker extends View { 

    Paint paint; 
    Path bodyPath; 
    Path dotPath; 
    private Paint paint2; 
    private int backGroundColor; 
    private int foreGroundColor; 
    Matrix scaleMatrix; 

    public CustomMapMarker(Context context) 
    { 
     super(context); 
     init(context); 

    } 

    public CustomMapMarker(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomMapMarker); 
     try { 
      backGroundColor = a.getColor(R.styleable.CustomMapMarker_markerBackgroundColor, Color.parseColor("#4180e0")); 
      foreGroundColor = a.getColor(R.styleable.CustomMapMarker_dotBackgroundColor, Color.WHITE); 
     } 
     finally { 
      a.recycle(); 
     } 
     init(context); 

    } 

    public CustomMapMarker(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     init(context); 
    } 

    private void init(Context context) { 
     scaleMatrix = new Matrix(); 
     bodyPath = new Path(); 
     dotPath = new Path(); 

     paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     paint.setStyle(Paint.Style.FILL); 
     paint.setColor(backGroundColor); 

     paint2 = new Paint(Paint.ANTI_ALIAS_FLAG); 
     paint2.setStyle(Paint.Style.FILL); 
     paint2.setColor(foreGroundColor); 
    } 

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    @Override 
    public void onDraw(Canvas canvas) 
    { 


     bodyPath.setFillType(Path.FillType.EVEN_ODD); 

     bodyPath.moveTo(132, 416); 
     bodyPath.cubicTo(123, 370, 107, 332, 87, 297); 
     bodyPath.cubicTo(72, 270, 55, 246, 39, 221); 
     bodyPath.cubicTo(33, 212, 29, 203, 24, 194); 
     bodyPath.cubicTo(14,177,5,156, 6, 130); 
     bodyPath.cubicTo(6,104,14,83,25,66); 
     bodyPath.cubicTo(42,38,72,15,112,9); 
     bodyPath.cubicTo(145, 4, 176,12,197,25); 
     bodyPath.cubicTo(215, 36, 229,49,239,66); 
     bodyPath.cubicTo(250, 83, 258, 103,258,129); 
     bodyPath.cubicTo(259, 143, 256, 155, 253, 166); 
     bodyPath.cubicTo(250, 176, 245, 185, 241, 194); 
     bodyPath.cubicTo(232, 212, 221, 229, 210, 246); 
     bodyPath.cubicTo(177, 296, 146, 347, 132, 416); 


     bodyPath.close(); 

     dotPath.setFillType(Path.FillType.EVEN_ODD); 
     dotPath.arcTo(82, 85, 182, 185, 270, 360, true); 
     dotPath.close(); 

     bodyPath.addPath(dotPath); 

     RectF drawableRect = new RectF(0, 0, 265, 412); 
     RectF viewRect = new RectF(0, 0, getWidth(), getHeight()); 
     scaleMatrix.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER); 
     bodyPath.transform(scaleMatrix); 
     dotPath.transform(scaleMatrix); 

     canvas.drawPath(bodyPath, paint); 
     canvas.drawPath(dotPath, paint2); 

    } 


    public void setBackgroundColor(int mColor) { 
     this.backGroundColor = mColor; 
     this.invalidate(); 
    } 

    public void setForeGroundColor(int mColor) { 
     this.foreGroundColor = mColor; 
     this.invalidate(); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

     int desiredWidth = 255; 
     int desiredHeight = 412; 

     int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
     int widthSize = MeasureSpec.getSize(widthMeasureSpec); 
     int heightMode = MeasureSpec.getMode(heightMeasureSpec); 
     int heightSize = MeasureSpec.getSize(heightMeasureSpec); 

     int width; 
     int height; 

     if (widthMode == MeasureSpec.EXACTLY) { 
      width = widthSize; 
     } else if (widthMode == MeasureSpec.AT_MOST) { 
      width = Math.min(desiredWidth, widthSize); 
     } else { 
      width = desiredWidth; 
     } 

     if (heightMode == MeasureSpec.EXACTLY) { 
      height = heightSize; 
     } else if (heightMode == MeasureSpec.AT_MOST) { 
      height = Math.min(desiredHeight, heightSize); 
     } else { 
      height = desiredHeight; 
     } 

     setMeasuredDimension(width, height); 
    } 


} 

其中在XML預覽,顯示爲意:

enter image description here

然而,在運行時,將此標記嵌入到應用程序的某個位置進行測試,白點不可見?

enter image description here

會有人用自定義視圖更多的經驗可以提供一些線索這光?我認爲這與我擴大路徑以適應任何尺寸的方式有關?

+0

不要使用硬編碼的數字,用getWidth()和getHeight()計算路徑和這些百分比,那麼根本不需要縮放。爲什麼將dotpath添加到bodypath?在你的setXXXColor函數中,你必須使用paint.setColor(),否則它們將不起作用。 – ElDuderino

+0

@ElDuderino感謝您的回覆,在setXXXColors上打了很好的電話,他們現在沒有實際使用,但稍後會刺痛我!不幸的是,關於縮放,我對程序繪圖和/或自定義視圖非常缺乏經驗,並且嘗試使用您提到的正確方法很少有成功! – Broak

回答

0

我終於找到了一些時間來看看你的問題。

1)使用addArc()而不是arcTo()。如果你想要的只是一個圓圈,不要使用路徑,請使用canvas.drawCircle()。我會那樣做。

2)不要在onDraw()中創建對象。使用onSizeChanged()來創建你的路徑,那是你知道你的視圖有多大的時候。然後,您可以根據視圖的寬度和高度來計算路徑。因此你不需要擴展任何東西。在onDraw()你只需繪製。

@Override 
public void onSizeChanged(int width, int height, int oldWidth, int oldHeight) { 
    bodyPath = getBodyPath(width, height); 
    dotPath = getDotPath(width, height); 
} 

@Override 
public void onDraw(Canvas canvas) 
{ 
    canvas.save(); 
    if(bodyPath != null) { 
     canvas.drawPath(bodyPath, backgroundPaint); 
    } 

    if(dotPath != null) { 
     canvas.drawPath(dotPath, foregroundPaint); 
    } 

    //or just a circle 
    //canvas.drawCircle(getWidth()/2, getHeight()/3,Math.min(getWidth(),getHeight())/5,foregroundPaint); 

    canvas.restore(); 
} 

getBodyPath()例如看起來像這樣

private Path getOutlinePath(float w, float h) { 
    Path bodyPath = new Path(); 
    bodyPath.setFillType(Path.FillType.EVEN_ODD); 
    bodyPath.moveTo(w* 0.5f, h); 
    bodyPath.cubicTo(w * 0.4f, h * 0.8f, w * 0.3f, h * 0.7f, w * 0.25f, h * 0.6f); 
    bodyPath.cubicTo(w * 0.2f, h * 0.5f, w * 0.1f, h * 0.5f, 0, h * 0.3f); 
    bodyPath.cubicTo(0, h * 0.25f, w * 0.25f, 0, w * 0.5f, 0); 
    bodyPath.cubicTo(w * 0.75f, 0, w, h * 0.25f, w, h * 0.5f); 
    bodyPath.close(); 
    return bodyPath; 
} 

是的,這是一個醜陋的路徑,但你可以看到我如何使用視圖的寬度和高度來計算控制點。這樣你就不需要你的縮放矩陣,也不需要onMeasure()。路徑將適合任何尺寸。