左上透明三角形与画布

时间:2019-03-22 13:04:13

标签: android canvas shapes

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

enter image description here

但这是我的结果:

enter image description here

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

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"/>

我想在几天前解决这个问题,但是没有运气!有人可以帮助我吗?

提前谢谢!

1 个答案:

答案 0 :(得分:0)

我找到了解决方法。

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对其进行了更改,并且进行了一些更改,效果很好!