【问题标题】:create View with curved edge and rounded corners in android在android中创建具有弯曲边缘和圆角的视图
【发布时间】:2022-01-10 12:33:55
【问题描述】:

我正在尝试在 android 中制作一个自定义视图,就像图片中的曲线边缘和圆角一样。如何做到这一点?

【问题讨论】:

  • 请在这里分享您的xml代码,以便给出解决方案。
  • 如果是背景,您可以创建一个 svg,例如Adobe Illustrator,然后将其作为 XML 资源导入。

标签: java android kotlin view viewgroup


【解决方案1】:

不久前我尝试为这个(松鼠)形状创建一个自定义视图。 虽然它不完整,但它会给你一个关于如何绘制这些形状的基本概念。顺便说一句,您需要禁用其父视图的 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
    }
}

【讨论】:

    【解决方案2】:
    1. ShapeDrawable 用于绘制原始形状的对象。您可以创建任何自定义形状,而不是创建自定义视图。
    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. 使用 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>
    

    【讨论】:

      【解决方案3】:
      1. 如果您想创建视图,最简单的方法是将布局包装在卡片视图中,然后添加卡片角半径。
      <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>
      
      

      参考:Google Docs

      1. 如果您想创建一个像您提到的照片一样的图标 .. 只需在任何 illustrator 软件中创建该图像,然后从 drawable>[右键单击]>图像资产中覆盖您的 android 图标

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-28
        • 2018-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多