2016-04-01 12 views
0

私は、下記のコード実行時にGoogleマップマーカーを生成するカスタムビューを書いた:カスタムビューの一部が実行時にレンダリングされませんか?

意図したとおりに表示されるXMLのプレビューでは、
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); 
    } 


} 

enter image description here

をしかし、時をランタイム、このマーカーをテストするアプリのどこかに埋め込むと、白い点は見えませんか?

enter image description here

カスタムビューでより多くの経験を持つ誰もがこの上でいくつかの光を当てることはできますか?私はそれがどんなサイズにも合うように経路を拡大する方法とは何かをしていると思いますか?

+0

ハードコードされた数値を使用せず、getWidth()およびgetHeight()でパスを計算し、それらのパーセンテージを使用すると、スケーリングはまったく必要ありません。なぜボディパスにドットパスを追加するのですか?あなたのsetXXXColor関数では、paint.setColor()を使う必要があります。そうしないと効果はありません。 – ElDuderino

+0

@ ElDuderino応答のためにありがとう、setXXXColorsの良い呼び出し、彼らは実際には現在使用されていませんが、後で私を刺されたでしょう!残念ながら、スケーリングに関しては、私はプログラミングの図面やカスタムビューでは非常に経験の浅いので、あなたが言及した適切な方法を試みることはほとんど成功しませんでした! – Broak

答えて

0

私はついにあなたの問題を見て時間を見つけました。

1)arcTo()の代わりにaddArc()を使用します。必要なものが円であれば、パスを使用せずに、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()を必要としません。パスは任意のサイズに適合します。