【问题标题】:Top left transparent triangle with canvas带画布的左上透明三角形
【发布时间】:2019-03-22 13:04:12
【问题描述】:

我尝试创建一个自定义形状来完成此操作:

但这是我的结果:

我创建了一个自定义视图,并绘制了一个带有左上角空白区域(三角形)的矩形边框。这是自定义类:

class MatchTriangleImageView : ImageView {

private var mCanvas: Canvas? = null
private var paint: Paint? = null
private var path: Path? = null
private var mWidth = 0
private var mHeight = 0
private val mPaintClear = Paint()

@JvmOverloads
constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0)
        : super(context, attrs, defStyleAttr)

init {

    mCanvas = Canvas()
    paint = Paint()
    paint?.isAntiAlias = true
    paint?.alpha = 0
    paint?.strokeJoin = Paint.Join.ROUND
    paint?.strokeCap = Paint.Cap.ROUND
    paint?.color = Color.TRANSPARENT

    paint?.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)

    path = Path()

    mPaintClear.color = Color.TRANSPARENT
    mPaintClear.style = Paint.Style.FILL
}

override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
    super.onSizeChanged(w, h, oldw, oldh)
    mWidth = w
    mHeight = h

}

override fun onDraw(canvas: Canvas?) {
    super.onDraw(canvas)

    canvas?.drawPaint(mPaintClear)

    drawable?.let {

        val triangleSize = 90f
        path?.fillType = Path.FillType.INVERSE_EVEN_ODD

        path?.moveTo(triangleSize, 0f)
        path?.lineTo(mWidth.toFloat(), 0f)//top right
        path?.lineTo(mWidth.toFloat(), mHeight.toFloat())//bottom right
        path?.lineTo(0f, mHeight.toFloat())//bottom left
        path?.lineTo(0f, triangleSize)//top left
        path?.lineTo(triangleSize, 0f)

        path?.close()
        canvas?.drawPath(path, paint)
    }
}
}

这是我放置自定义视图的布局:

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardElevation="0dp"
app:cardCornerRadius="0dp"
android:background="@color/transparent">

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/transparent"
    android:clipToPadding="false"
    android:clipChildren="false">

    <com...MatchTriangleImageView
        android:id="@+id/matchCarViewImageWithTriangleIv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:adjustViewBounds="true"
        android:cropToPadding="true"
        android:scaleType="centerCrop"/>

我该如何解决这个问题?

【问题讨论】:

    标签: android canvas shapes


    【解决方案1】:

    我找到了解决办法。

    class MatchTriangleImageView : ImageView {
    
    private var mPaint : Paint? = null
    private var path: Path? = null
    private var mWidth = 0
    private var mHeight = 0
    private var rect : Rect? = null
    
    var triangleSize = 0f
    
    @JvmOverloads
    constructor(
            context: Context,
            attrs: AttributeSet? = null,
            defStyleAttr: Int = 0)
            : super(context, attrs, defStyleAttr)
    
    
    init {
    
        val triangleRes : BitmapDrawable? = ContextCompat.getDrawable(context, R.drawable.white_match_triangle) as BitmapDrawable
        triangleSize = triangleRes?.bitmap?.height!!.toFloat()
    
        setLayerType(View.LAYER_TYPE_SOFTWARE, null)
    
        mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        mPaint?.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
        mPaint?.color = Color.TRANSPARENT
        mPaint?.strokeWidth = 5f
        mPaint?.strokeJoin = Paint.Join.ROUND
        mPaint?.strokeCap = Paint.Cap.ROUND
    
        path = Path()
    
    }
    
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
    
        super.onSizeChanged(w, h, oldw, oldh)
        mWidth = w
        mHeight = h
    
        rect = Rect(0,0,w,h)
        path?.fillType = Path.FillType.INVERSE_EVEN_ODD
    
        path?.reset()
        path?.moveTo(triangleSize, 0f)
        path?.lineTo(mWidth.toFloat(), 0f)//top right
        path?.lineTo(mWidth.toFloat(), mHeight.toFloat())//bottom right
        path?.lineTo(0f, mHeight.toFloat())//bottom left
        path?.lineTo(0f, triangleSize)//top left
        path?.lineTo(triangleSize, 0f)
    
        path?.close()
    
    }
    
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
    
        drawable?.let {
    
            canvas.drawPath(path!!, mPaint!!)
        }
    
    }
    

    }

    我把这个自定义视图放在一个 CardView 组件中,但是这个组件不喜欢画布透明度。我通过 FrameLayout 对其进行了更改,并进行了一些小的更改,成功了!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-04
      • 1970-01-01
      • 2017-01-14
      • 1970-01-01
      • 1970-01-01
      • 2019-07-26
      • 1970-01-01
      相关资源
      最近更新 更多