android - Android CardView 圆角在 27 之前在 Android API 上被破坏
问题描述
我在具有圆角的父 CardView 中嵌入了卡片视图(我将此父卡片视图命名为 CV1)。当我滚动CV1的内容时,子cardview与CV1重叠并取消了CV1的圆角(如视频中的箭头所示),另一方面TextView,ImageView被很好地裁剪,我们总是看到圆角的地图。请参阅:threadvintage:注意:这只发生在 Android API <= 27 的版本上,在 APIs> 28 上一切都很好。
即使我添加app:cardPreventCornerOverlap="true"
和
app:cardUseCompatPadding="true"
下面的代码
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
fibe:cardCornerRadius="15dp"
android:layout_margin="32dp">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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>
视频可在此处获得。
使用 Android API 24 在平板电脑上渲染:我们这里有错误
使用 Android API 28 在平板电脑上渲染:一切都很好
更新 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_width="216dp"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:orientation="vertical">
<androidx.cardview.widget.CardView
style="@style/RoundedCornersContentItem"
android:layout_width="match_parent"
android:layout_height="148dp"
app:cardElevation="0dp"
app:cardBackgroundColor="@color/content_item_badge_background"/>
<TextView
style="@style/FlowPanelHeaderTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="Very long title for my card" />
</LinearLayout>
解决方案
这在 API 27 及以下版本中肯定被破坏了。这似乎是一个已知问题,但我没有看到任何解决方法。
以下布局,根据您的布局稍作修改,如果有人想看一下,将重现该问题。
activity_main.xml
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="32dp"
app:cardCornerRadius="15dp">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="32dp"
app:cardCornerRadius="15dp">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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尊重这些角落。
代替彻底修复,一种解决方法是创建一个自定义CardView来完成它自己的角剪裁。这是这样一个自定义视图:
MyCardView.kt
类 MyCardView @JvmOverloads 构造函数(上下文:上下文,attrs:AttributeSet?= null):CardView(上下文,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的演示:
推荐阅读
- spring - 500 内部服务器错误 Spring boot & JWT
- php - 通过 phpMyAdmin 触发对数据库中所有条目的更新
- sql - SQL:从字符串中提取一个单词
- regex - 正则表达式搜索文件中的部分或文本块中的内容
- ios - 在启用分页的情况下检测滚动视图中取消的滚动
- chart.js - 图表 js 中的borderdash 选项改变了我的图例
- linux - 使用 sed 获取两个模式第一次出现之间的文本
- json - 使用 InMemoryDatabase Angular 8 的 PUT 请求和查询参数
- python - 如何使用 PyTorch 从 3D 张量中删除元素?
- ios - 在 iOS 13 中实现自定义 ImagePickController