2017-11-24 11 views
0

円形の表面ビュー(ポートホール効果)を作成したいと思います。サーフェスビューはフレームレイアウト内にあります。サーフェイスビューの上にフレームレイアウトを追加し、フレームレイアウト全体をマスクしてポートホールエフェクトを作成し、サーフェスビューをサークルとして表示するカスタムビューを作成したいと思います。親をマスクし、親の中心に透明円を描くカスタムビュー

私は検索し、WebとStackoverflowで多くの回答が失敗しました。 それから、私はthis質問を見ました。このカスタムビューをフレームレイアウト(したがってsurfaceview)にマスクしようとしましたが、望みの結果が得られません。

私が望むのは、親の高さと幅(親は正方形です)をとり、境界の真ん中で4辺すべてに触れる中央で透明な円を作ります(ビュー - サークル)は、私が設定できる色で表示されます。

public class FocusView extends View { 

private Paint mTransparentPaint; 
private Paint mSemiBlackPaint; 
private Path mPath = new Path(); 

public static float radius , xCor , yCor; 

public FocusView(Context context) { 
    super(context); 
    initPaints(); 
} 

public FocusView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    initPaints(); 
} 

public FocusView(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    initPaints(); 
} 

private void initPaints() { 
    mTransparentPaint = new Paint(); 
    mTransparentPaint.setColor(Color.GREEN); 
    mTransparentPaint.setStrokeWidth(10); 

    mSemiBlackPaint = new Paint(); 
    mSemiBlackPaint.setColor(Color.TRANSPARENT); 
    mSemiBlackPaint.setStrokeWidth(10); 
} 

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

    mPath.reset(); 

    mPath.addCircle(xCor,yCor,radius, Path.Direction.CW); 
    mPath.setFillType(Path.FillType.INVERSE_EVEN_ODD); 

    canvas.drawCircle(xCor,yCor,radius, mTransparentPaint); 

    canvas.drawPath(mPath, mSemiBlackPaint); 
    canvas.clipPath(mPath); 
    canvas.drawColor(Color.parseColor("#FFFFFF"));  //A6000000 
} 

} 

誰かが私を助けることができたらどうかしてください。前もって感謝します。

+0

これはあなたに役立つでしょうか?すべてがxmlではありません。https://stackoverflow.com/questions/46972667/how-to-create-a-complete-round-linearlayout-or-relativelayout/46972897#46972897 – Xenolion

答えて

1

これは全体ビューピンク塗料と親が見えるように中心に円形の穴をカットする図の一例である:


public class FocusView extends View { 

    private Paint mCutPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    private Bitmap mBitmap; 
    private Canvas mInternalCanvas; 

    public FocusView(Context context) { 
     super(context); 
     init(); 
    } 

    public FocusView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(); 
    } 

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

    private void init() { 
     mCutPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 

     if (mInternalCanvas != null) { 
      mInternalCanvas.setBitmap(null); 
      mInternalCanvas = null; 
     } 

     if (mBitmap != null) { 
      mBitmap.recycle(); 
      mBitmap = null; 
     } 

     mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     mInternalCanvas = new Canvas(mBitmap); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     if (mInternalCanvas == null || mBitmap == null) { 
      return; 
     } 

     final int width = getWidth(); 
     final int height = getHeight(); 

     // make the radius as large as possible within the view bounds 
     final int radius = Math.min(width, height)/2; 

     mInternalCanvas.drawColor(0xFFFF00FF); 
     mInternalCanvas.drawCircle(width/2, height/2, radius, mCutPaint); 

     canvas.drawBitmap(mBitmap, 0, 0, null); 
    } 
} 

第一内部Bitmapに描画するための理由は、あなたが適用される場合ということですPorterDuff.Mode.CLEARを元のCanvasに変更すると、以前に親ビューを含めてキャンバスに描画されているすべてのものが削除されます。

もっと良い解決策があるかもしれませんが、これは理解するのに十分単純です。

+0

これはうまくいきました、ありがとう。 –

+0

** mInternalCanvas **の使用方法を教えてください。 –

+1

'mInternalCanvas'は、一時的なビットマップに描画するために使用されます。 'onDraw'に与えられたキャンバスで' mCutPaint'を使うと、ビューの前に描画されたすべてのものが切り取られるので、親の穴をカットしてカットスルーの代わりに黒い円になります親にしかし、最初に自分のCanvasに描画する場合は、すべてを安全にカットし、結果を 'onDraw'によって提供されるキャンバスに描画するだけです。私はそれをクリアすることを願っています。それ以外の場合は、元のキャンバスに描画コマンドを適用し、自分のために何が起こるか見ることができます:) –

関連する問題