Android CardView 圆角在 27 之前在 Android API 上被破坏

Posted

技术标签:

【中文标题】Android CardView 圆角在 27 之前在 Android API 上被破坏【英文标题】:Android CardView rounded corner broken on Android API before 27 【发布时间】:2021-10-24 21:45:41 【问题描述】:

我在具有圆角的父 CardView 中嵌入了卡片视图(我将此父 CardView 命名为 CV1)。当我滚动CV1的内容时,子cardview与CV1重叠并取消了CV1的圆角(如视频中的箭头所示),另一方面TextView,ImageView被很好地裁剪,我们总是看到圆角的地图。请参阅:线程年份: 注意:这只发生在 android API 28 上一切正常。

即使我添加 app:cardPreventCornerOverlap="true"app:cardUseCompatPadding="true"

代码如下

<androidx.cardview.widget.CardView
android:layout_
android:layout_
fibe:cardCornerRadius="15dp"
android:layout_margin="32dp">

<ScrollView
    android:layout_
    android:layout_>
    
    <LinearLayout
        android:layout_
        android:layout_
        android:orientation="vertical">
        
        <include layout="@layout/item_list" />
        <include layout="@layout/item_list" />
        <include layout="@layout/item_list" />
        <include layout="@layout/item_list" />
        <include layout="@layout/item_list" />
        <include layout="@layout/item_list" />
        <include layout="@layout/item_list" />
        <include layout="@layout/item_list" />
    </LinearLayout>
</ScrollView>
</androidx.cardview.widget.CardView>

这里有视频。

Rendering on Tablet with Android API 24 : We have error here

Rendering on Tablet with Android API 28 : Everything is good here

更新 1:item_list 布局代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_
    android:layout_
    android:layout_marginStart="16dp"
    android:orientation="vertical">

    <androidx.cardview.widget.CardView
        style="@style/RoundedCornersContentItem"
        android:layout_
        android:layout_
        app:cardElevation="0dp"
 app:cardBackgroundColor="@color/content_item_badge_background"/>

    <TextView
        style="@style/FlowPanelHeaderTitle"
        android:layout_
        android:layout_
        android:layout_marginTop="4dp"
        android:text="Very long title for my card" />

</LinearLayout>

【问题讨论】:

this 是不是同样的问题? @Cheticamp 它是相似的。就我而言,我没有使用 MaterialCardView MaterialCardview 扩展了 CardView,所以我认为这可能是同一个问题。 this bug report 似乎也能识别它。您可以发布 item_list 布局的 XML 吗? @Cheticamp 查看代码更新中的item_list 布局.. 【参考方案1】:

这在 API 27 及更低版本上肯定被破坏了。这似乎是一个已知问题,但我没有看到任何解决方法。

以下布局,根据您的布局稍作修改,如果有人想查看,将重现该问题。

activity_main.xml

<androidx.cardview.widget.CardView 
    android:layout_
    android:layout_
    android:layout_margin="32dp"
    app:cardCornerRadius="15dp">

    <ScrollView
        android:layout_
        android:layout_>

        <LinearLayout
            android:layout_
            android:layout_
            android:background="@android:color/holo_blue_light"
            android:orientation="vertical">

            <include layout="@layout/item_list" />

            <include layout="@layout/item_list" />

            <include layout="@layout/item_list" />

            <include layout="@layout/item_list" />

            <include layout="@layout/item_list" />

            <include layout="@layout/item_list" />

            <include layout="@layout/item_list" />

            <include layout="@layout/item_list" />
        </LinearLayout>
    </ScrollView>
</androidx.cardview.widget.CardView>

item_list.xml

<androidx.cardview.widget.CardView 
    android:layout_
    android:layout_
    android:layout_margin="32dp"
    app:cardCornerRadius="15dp">

    <ScrollView
        android:layout_
        android:layout_>

        <LinearLayout
            android:layout_
            android:layout_
            android:background="@android:color/holo_blue_light"
            android:orientation="vertical">

            <include layout="@layout/item_list" />

            <include layout="@layout/item_list" />

            <include layout="@layout/item_list" />

            <include layout="@layout/item_list" />

            <include layout="@layout/item_list" />

            <include layout="@layout/item_list" />

            <include layout="@layout/item_list" />

            <include layout="@layout/item_list" />
        </LinearLayout>
    </ScrollView>
</androidx.cardview.widget.CardView>

这是一个 API 27 模拟器的演示:

我不能确切地说出问题是什么,奇怪的是嵌套的 CardView 覆盖了外部 CardView 的角,而 TextView em> 尊重那些角落。

代替彻底的修复,一种解决方法是创建一个自定义的CardView,它可以自己进行角落剪辑。这是这样一个自定义视图:

MyCardView.kt

class MyCardView @JvmOverloads 构造函数( 上下文:上下文,属性:属性集? =空 ) : CardView(context, attrs)

    private lateinit var mRectF: RectF
    private val mPath = Path()
    private var mCornerRadius = 0f

    init 
        val a = context.obtainStyledAttributes(
            attrs, R.styleable.CardView, 0,
            R.style.CardView
        )
        mCornerRadius = a.getDimension(androidx.cardview.R.styleable.CardView_cardCornerRadius, 0f)
        a.recycle()
    

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) 
        super.onSizeChanged(w, h, oldw, oldh)
        mRectF = RectF(0f, 0f, w.toFloat(), h.toFloat())
        resetPath()
    

    override fun draw(canvas: Canvas) 
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) 
            canvas.withClip(mPath) 
                super.draw(canvas)
            
        
    

    private fun resetPath() 
        mPath.apply 
            reset()
            addRoundRect(mRectF, mCornerRadius, mCornerRadius, Path.Direction.CW)
            close()
        
    

这是在同一个 API 27 模拟器上使用自定义 CardView 的演示:

【讨论】:

以上是关于Android CardView 圆角在 27 之前在 Android API 上被破坏的主要内容,如果未能解决你的问题,请参考以下文章

Android5.0之CardView的使用

Android开发之CardView的使用

使用CardView实现圆角或圆形的效果

使用CardView实现圆角或圆形的效果

android CardView,LinearCardView,RelativeCardView自定义和使用

android CardView,LinearCardView,RelativeCardView自定义和使用