简体   繁体   English

在 android 中创建具有弯曲边缘和圆角的视图

[英]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.我正在尝试在 android 中制作一个自定义视图,就像图中带有曲线边缘和圆角的图片一样。 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.顺便说一句,您需要禁用其父视图的 clipChildren 以修复剪辑。

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如果您想创建一个像您提到的照片一样的图标.. 只需在任何插画软件中创建该图像,然后从 drawable>[右键单击]>图像资产覆盖您的 android 图标
  1. ShapeDrawable object used for drawing primitive shapes. ShapeDrawable object 用于绘制原始形状。 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.使用 android xml结构来创建形状。
<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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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