1

I try to create a custom shape to accomplish this:

enter image description here

But this is my result:

enter image description here

I have created a custom view and I paint a rectangle border with a top left empty space (with a triangle shape). This is the custom class:

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)
    }
}
}

And this this the layout where I put the custom view:

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

How can I solve this?

halfer
  • 19,824
  • 17
  • 99
  • 186
Sami Issa
  • 1,695
  • 1
  • 18
  • 29

1 Answers1

0

I found out the solution.

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!!)
    }

}

}

I putted this custom view in a CardView component, but this component doesn't like canvas transparency. I changed it by FrameLayout, and with some litle changes, worked!!

Sami Issa
  • 1,695
  • 1
  • 18
  • 29