简体   繁体   中英

create View with curved edge and rounded corners in android

I am trying to make a custom view in android like in the picture with curve edges and rounded corners. How to achieve this?

在此处输入图像描述

I've tried to create a custom view for this (squircle) shape a while ago. Although it's not complete, it'll give you a basic idea on how to draw such shapes. By the way you'll need to disable clipChildren of its parent view to fix clipping.

package com.certainlyaria.squircle

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View


class SquircleView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    private val paint = Paint().apply {
        color = Color.MAGENTA
        isAntiAlias = true
        style = Paint.Style.STROKE
        strokeJoin = Paint.Join.ROUND
        strokeWidth = 10f
    }

    companion object {
        private const val CURVE = 75f
    }

    private val clipPath = Path()

    private var smooth = Path()

    private val clipRect = RectF(
        CURVE, CURVE, 0f, 0f
    )

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

        clipRect.apply {
            right = w - CURVE
            bottom = h - CURVE
        }
        clipPath.apply {
            rewind()
            moveTo(0f, (width) / 2f)
            cubicTo(
                0f,
                0f,
                (width) / 4f,
                0f,
                (width) / 2f,
                0f
            )
            cubicTo(
                (width) * 3 / 4f,
                0f,
                width.toFloat(),
                0f,
                width.toFloat(),
                width / 2f
            )
            cubicTo(
                width.toFloat(),
                width.toFloat(),
                width * 3f / 4,
                width.toFloat(),
                (width) / 2f,
                width.toFloat()
            )
            cubicTo(
                width / 4f,
                width.toFloat(),
                0f,
                width.toFloat(),
                0f,
                (width) / 2f
            )
        }

        smooth = getSquirclePaath(0, 0, width / 2)
    }

    override fun onDraw(canvas: Canvas) {
        canvas.save()
        canvas.drawPath(clipPath, paint)
        //canvas.drawPath(smooth, paint)
        canvas.restore()
    }

    private fun getSquirclePaath(
        left: Int,
        top: Int,
        radius: Int
    ): Path { //Formula: (|x|)^3 + (|y|)^3 = radius^3
        val radiusToPow = radius * radius * radius.toDouble()
        val path = Path()
        path.moveTo((-radius).toFloat(), 0f)
        for (x in -radius..radius) path.lineTo(
            x.toFloat(),
            Math.cbrt(radiusToPow - Math.abs(x * x * x)).toFloat()
        )
        for (x in radius downTo -radius) path.lineTo(
            x.toFloat(),
            (-Math.cbrt(radiusToPow - Math.abs(x * x * x))).toFloat()
        )
        path.close()
        val matrix = Matrix()
        matrix.postTranslate((left + radius).toFloat(), (top + radius).toFloat())
        path.transform(matrix)
        return path
    }
}
  1. if you want to create a view the the easiest way to do that is by wrapping your layout in a cardview and then add a card corner radius.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    ... >
    <!-- A CardView that contains a TextView -->
    <androidx.cardview.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view"
        android:layout_gravity="center"
        android:layout_width="200dp"
        android:layout_height="200dp"
        card_view:cardCornerRadius="4dp">

        <TextView
            android:id="@+id/info_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </androidx.cardview.widget.CardView>
</LinearLayout>

Ref: Google Docs

  1. If you want to create an icon like the photo you mentioned.. It's just a matter of creating that image in any illustrator software and then override your android icon from drawable>[right-click]>image asset
  1. ShapeDrawable object used for drawing primitive shapes. You can create any custom shape instead of creating custom view.
RoundRectShape roundRectShape = new RoundRectShape(new float[]{
10, 10, 10, 10,
10, 10, 10, 10}, null, null);
ShapeDrawable shapeDrawable = new ShapeDrawable(roundRectShape);
shapeDrawable.getPaint().setColor(Color.parseColor(“#FFFFFF”));
ImageView myImageView = findViewById(R.id.my_image_view);
myImageView.setBackground(shapeDrawable);
  1. Use android xml structure for creating shapes.
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <corners
        android:bottomRightRadius="10dp"
        android:radius="40dp" />

    <gradient
        android:angle="45"
        android:centerX="float"
        android:centerY="float"
        android:endColor="#01f1fa"
        android:gradientRadius="integer"
        android:startColor="#0189ff"
        android:type="linear" />

    <!--If your shape requires only one solid color-->
    <!--<solid
        android:color="#FFFFFF" />-->

    <size
        android:width="82dp"
        android:height="82dp" />

    <!--Use android:dashWidth="2dp" and android:dashGap="2dp"
    to add dashes to your stroke-->
    <stroke
        android:width="2dp"
        android:color="#FFFFFF" />

    <!--If you want to add padding-->
    <!-- <padding
         android:left="10dp"
         android:top="20dp"
         android:right="40dp"
         android:bottom="8dp" />-->
    
</shape>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM