您现在的位置是:首页 > 正文

Android CardView如何显示出底背景样式?

2024-04-01 00:32:54阅读 1
<androidx.cardview.widget.CardView
    android:id="@+id/actionOneCv"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:foreground="?android:attr/selectableItemBackground"
    app:cardCornerRadius="0dp"
    app:cardElevation="0dp"/>

常使用上述的写法来实现一个button样式。

问题一:
如果将其放入在一个dialog的bottom位置作为点击按钮,dialog的background设置了圆角,但是显示button一角却还是直角。

问题二:
此时dialog更改bg颜色,发现CardView区域还是白色。

针对问题一,当然可以更改CardView来手动设置某一部分是圆角。
但两个问题的症结其实都是同一个点,那就是:

设置水波纹foreground的CardView默认背景就是白色

解决方案:将默认背景改为透明,则就能显示出dialog底背景的样式了。
<androidx.cardview.widget.CardView
android:id="@+id/actionOneCv"
android:layout_width=“0dp”
android:layout_height=“match_parent”
android:layout_weight=“1”
app:cardBackgroundColor="@color/transparent"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius=“0dp”
app:cardElevation=“0dp”/>

可以看到此处是设置app:cardBackgroundColor="@color/transparent".

问题来了,上述的方法只能设置color,如果要设置drawable该怎么办?
其实解决方案很简单:CardView本身是继承自FrameLayout的,这就意味着它是可以包裹内容的,里面包裹其它控件(如ImageView)。通过包裹的控件来实现有drawable的背景即可。

那么又有问题了,既然CardView继承自FrameLayout,这就说明其是可以设置Background的。但为什么设置后却显示不出来呢?

这个就涉及到整个View的构造流程了:

public CardView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
//省略属性获取
    IMPL.initialize(mCardViewDelegate, context, backgroundColor, radius,
            elevation, maxElevation);
}

初始化View进入构造方法,会进行IMPL.initialize方法的调用。这个IMPL是什么?

private static final CardViewImpl IMPL;

static {
    if (Build.VERSION.SDK_INT >= 21) {
        IMPL = new CardViewApi21Impl();
    } else if (Build.VERSION.SDK_INT >= 17) {
        IMPL = new CardViewApi17Impl();
    } else {
        IMPL = new CardViewBaseImpl();
    }
    IMPL.initStatic();
}

IMPL是CardView的实现类,不同的版本有不同的实现。此处进入CardViewApi21Impl里面看看initialize实现。

@Override
public void initialize(CardViewDelegate cardView, Context context,
            ColorStateList backgroundColor, float radius, float elevation, float maxElevation) {
    final RoundRectDrawable background = new RoundRectDrawable(backgroundColor, radius);
    cardView.setCardBackground(background);

    View view = cardView.getCardView();
    view.setClipToOutline(true);
    view.setElevation(elevation);
    setMaxElevation(cardView, maxElevation);
}

可以发现在这里面进行了cardView.setCardBackground调用,而background是根据设置的

backgroundColor = a.getColorStateList(R.styleable.CardView_cardBackgroundColor);

赋值RoundRectDrawable生成而来。
cardView.setCardBackground(background);中的CardView是CardViewDelegate,它是一个接口,所以也要看它的实现类。在CardView类中可以找到:

private final CardViewDelegate mCardViewDelegate = new CardViewDelegate() {
    private Drawable mCardBackground;

    @Override
    public void setCardBackground(Drawable drawable) {
        mCardBackground = drawable;
        setBackgroundDrawable(drawable);
    }
    //...
}

而上面的setBackgroundDrawable则是进入到了View层面了。

至此已经很清楚了,因为initialize在父类(FrameLayout)的构造方法之后调用,导致最终设置的setBackgroundDrawable会始终覆盖父类的该方法实现。

说到底,就是个实现的先后覆盖问题

网站文章

  • c#:grpc初体验

    c#:grpc初体验

    环境: window10x64 企业版 vs2019 16.7.7 .net core3.1 参照: 《ASP.NET Core 3.0 使用gRPC》 《Asp.Net Core Grpc使用C#对...

    2024-04-01 00:32:47
  • django 使用默认django数据库创建数据库

    django 使用默认django数据库创建数据库

    django有默认自带的数据库,当然也可以用其他的数据库,修改数据库的方式也很简单是需要在setting.py修改 DATABASES这里面的参数就可以了 DATABASES = { &#39;def...

    2024-04-01 00:32:21
  • centos boot dvd版本_华为LTE认证考试题库(Word版)

    centos boot dvd版本_华为LTE认证考试题库(Word版)

    资料共计129页,篇幅有限,本文只列举少部分试题。如需要原文档:请关注本公众号,并将本文分享到朋友圈或者是通信群组。分享后添加微信(微信号:tongxinzixun123)领取。这些资料是我从各大通信论坛上面所收集,版权归原作者所有,本号只提供分享,供通信人学习交流用,禁止用于商业等用途,谢谢大家的理解与支持!更多精彩内容,请点击下面链接查看并领取:4G网络优化典型案例(PPT版)5G现...

    2024-04-01 00:32:12
  • 苹果手机无法解析html,苹果手机故障全解析

    苹果手机无法解析html,苹果手机故障全解析

    苹果手机的的故障问题虽然有很多,不过依旧无法阻挡果粉们对它的爱。今天小编就为大家总结和介绍一下苹果手机都有哪些故障和解决办法!手机不像电脑是靠自身散热,大家最直观的感受就是手机操作一会发烫,怎么解决?...

    2024-04-01 00:32:04
  • 什么是美颜SDK?

    什么是美颜SDK?

    首先,美摄美颜SDK拥有丰富的美颜算法库,可以满足用户多样化的美颜需求。再者,它还具备出色的跨平台兼容性,可以轻松集成到各种设备和应用中,无论是手机、相机还是直播平台,都能发挥出其强大的功能。当然,针...

    2024-04-01 00:31:58
  • Jfinal 在tomcat启动报错!!

    看清楚,我的jfianl项目启动报错大概显示:java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component 什么原因呢?包也导够了,是从官方maven Demo拷贝过来的,在jetty server下可以启动,到部署到tom

    2024-04-01 00:31:30
  • ansible 流程控制

    ansible 流程控制使用when判断主机名- hosts: rsync_server tasks: - name: Install rsyncd Server yum: name: rsync state: present - name: Config rsyncd Conf copy: ...

    2024-04-01 00:31:23
  • angular路由传递参数

    angular路由传递参数

    1、 查询参数中传递数据 在a标签上添加一个参数queryParams &amp;amp;lt;a [routerLink]=&amp;quot;[&#39;/tab4&#39;]&amp;quot; [queryParams]=&amp;quot;{id:3}&amp;quot; &amp;amp;gt;tab4&amp;amp;lt;/a&amp;amp;gt; 此时此时除了rout

    2024-04-01 00:31:17
  • linux shell 除法运算符,Linux shell 基本运算符详解

    shell 支持多种运算符1.算数运算符2.关系运算符3.布尔运算符4.字符串运算符5.文件测试运算符原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr...

    2024-04-01 00:30:50
  • 《奔跑吧Linux内核(第二版)》第三章笔记

    《奔跑吧Linux内核(第二版)》第三章笔记

    ARM64架构基础知识

    2024-04-01 00:30:40