在 android Kotlin 中设计弯曲的容器/CardViews

Posted

技术标签:

【中文标题】在 android Kotlin 中设计弯曲的容器/CardViews【英文标题】:Designing Curved Containers/CardViews in android Kotlin 【发布时间】:2021-11-04 02:55:16 【问题描述】:

您好,我目前正在尝试实现与给定图像类似的东西。 谁能指导我如何在 Kotlin/xml 视图中查看外观? 我需要设计的部分是价格标签视图。

非常感谢

【问题讨论】:

CardView 包含 RelativeLayout 包含两个孩子:ImageView 用于图片,TextView 用于价格。第一个履行父母(match_parent),第二个与底部/右侧对齐。这是非常基本的布局,对于一些 android 学习来说是准确的...... 我在获取布局方面没有问题。我需要的部分是价格标签中的弯曲外观 【参考方案1】:

嗯,首先,您可以使用任何图形软件绘制文本背景,可能是photoshopadobe illustrator 用于矢量。我不太擅长这个软件,但我创建了一个与我们真正想要的非常相似的矢量图像。

所以在你的drawables 目录中创建一个新的drawable 文件,命名为tv_bg.xml,然后复制粘贴这个vector drawable。

tv_bg.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:
    android:
    android:autoMirrored="true"
    android:viewportWidth="196.739"
    android:viewportHeight="101.01">
    <path
        android:fillColor="#fff"
        android:pathData="M196.736,0.01L196.736,99.993L0,99.993s8.6,11.826 15.051,-45.153 93.532,-54.829 93.532,-54.829Z" />
</vector>

然后创建一个布局文件,我称之为my_layout.xml

my_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_
    android:background="@android:color/white"
    android:padding="8dp"
    android:layout_>

    <ImageView
        android:id="@+id/imageView"
        android:layout_
        android:layout_
        android:scaleType="centerCrop"
        android:src="@drawable/your_image_placeholder"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:layout_
        android:layout_
        android:text="$ 15.00"
        android:textSize="18sp"
        android:textStyle="bold"
        android:gravity="center"
        android:background="@drawable/tv_bg"
        android:textColor="@android:color/black"
        app:layout_constraintBottom_toBottomOf="@+id/imageView"
        app:layout_constraintEnd_toEndOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

这将是你的最终结果

当然,您需要稍微改进TextView 的背景和文字样式以匹配您真正想要的。

【讨论】:

我可以试试这个:)【参考方案2】:

如果我要实现它,我会

    自定义一个textView(我们称之为curdTextView)。也许在 onDraw 方法中,我会绘制一个与雕刻部分相似的背景(15,000 的背景)。一些坐标几何可以解决问题。形状很像一条切线曲线、指数曲线,或者只是两个有共同切线的圆......只需选择一个即可。 获得视图后,只需使用 constraintlayout、imageView 并将curdTextView 放置到bottomRignt 角。

我需要编写一些代码,并进行一些试验以提供示例代码。我稍后会尝试更新答案。很抱歉给您带来不便。

更新

所以在写了一些代码之后,这是我的curdTextView

package com.applications.ui

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.content.res.ResourcesCompat
import ridmik.one.R

class CurvedTextView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null
) : AppCompatTextView(context, attrs) 
    val TAG = "CurvedTextView"

    val white = ResourcesCompat.getColor(context.resources, R.color.colorSolidWhite, null)
    val transparentColor = ResourcesCompat.getColor(context.resources, R.color.transparent, null)

    val paint: Paint = Paint().apply 
        this.color = white
        this.style = Paint.Style.FILL_AND_STROKE
    
    val path: Path = Path()


    val paddingVertical: Float = getPxFromDp(context, 10.0).toFloat()
    val paddingHorizontal: Float = getPxFromDp(context, 20.0).toFloat()

    val delta: Float = getPxFromDp(context, 10.0).toFloat()  // random trial and error
    init
    

    fun getPxFromDp(context: Context, dp: Double): Double 
        return dp * context.resources.displayMetrics.density
    

    override fun draw(canvas: Canvas?) 
        if(canvas!=null) 
            path.moveTo(paddingHorizontal+delta, 0f)
            path.cubicTo(
                (paddingHorizontal - delta), delta,
                delta, height - delta,
                0f, height.toFloat()
            )
            path.lineTo(width.toFloat(), height.toFloat())
            path.lineTo(width.toFloat(), 0f)
            path.lineTo(paddingHorizontal+delta, 0f)

            canvas.drawPath(path, paint)
        
        super.draw(canvas)
    


现在只需在您的约束布局中添加:


<ImageView
    app:layout_constraintBottom_toBottomOf="parent"
    android:background="#FF0000"
    android:layout_
    android:layout_/>

    <com.applications.ui.CurvedTextView
    android:id="@+id/curvedTextView"
    android:text="$ 15,000"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    android:paddingVertical="10dp"
    android:paddingHorizontal="20dp"
    android:layout_
    android:layout_/>

输出:

现在您有了视图,尝试调整变量以使其完全符合您的要求。

【讨论】:

我正在尝试通过您提到的 1. 步骤。 你好,我写了一些代码,然后我更新了我的答案。所以现在你已经完成了第 1 步。请检查一下。 非常感谢您的精彩意见。我认为 android 在实现复杂形状方面存在很好的限制。 嗯,我认为这是一个几何问题。从这个意义上说,您需要做的就是以数学方式定义您的形状。您可以获得某些好处,例如,形状不会与您的文本重叠(在这种情况下是价格标签)。使用 Photoshop 中的可绘制背景可能无法保证这一点,因此您可能会遇到一些重叠。

以上是关于在 android Kotlin 中设计弯曲的容器/CardViews的主要内容,如果未能解决你的问题,请参考以下文章

在 Flutter for Android 中设计 UI

在 Android 中设计一个按钮

通过 JWT API 在 android 应用中设计身份验证

在 Android Studio 中设计可滚动内容时要遵循的方法是啥?

如何在android xml中设计4个可点击的圆形字段

在 Android Kotlin 的约束布局中设置适当的约束