CardView全面解析

CardView相信大家都并不陌生,但是我们开发过程中大多数只关心如何使用是远远不够的,需要我们去了解google开发人员设计这个控件的原因;

通过原码我们不难发现CardView是继承至FrameLayout,位于 android.support.v7.widget包下;

通过静态块初始化了成员变量CardViewImpl(是一个接口)

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

    IMPL.initStatic();
}

通过CardViewImpl针对不同的api版本进行了兼容和管理

然后重写了onMeasure方法

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (!(IMPL instanceof CardViewApi21Impl)) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode;
        switch(widthMode) {
        case -2147483648:
        case 1073741824:
            heightMode = (int)Math.ceil((double)IMPL.getMinWidth(this.mCardViewDelegate));
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(Math.max(heightMode, MeasureSpec.getSize(widthMeasureSpec)), widthMode);
        case 0:
        default:
            heightMode = MeasureSpec.getMode(heightMeasureSpec);
            switch(heightMode) {
            case -2147483648:
            case 1073741824:
                int minHeight = (int)Math.ceil((double)IMPL.getMinHeight(this.mCardViewDelegate));
                heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.max(minHeight, MeasureSpec.getSize(heightMeasureSpec)), heightMode);
            case 0:
            default:
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }
        }
    } else {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

}

在onmeasure方法中根据不同的情况对布局进行了重新测量;

我们知道因为系统自带的控件不能识别我们自定义的属性,所以CardView就采用自定义FrameLayout布局来包括系统原生控件,

通过CardViewImpl来操作整个布局的LayoutParams,从而达到满足各种效果的目的,这也是google设计这个控件的初衷;

下面就针对CardView常用的属性做个汇总:

  <!--app:cardBackgroundColor="@color/colorPrimary"  设置cardView背景色 -->
    <!--app:cardPreventCornerOverlap="false" 取消Lollipop以下版本的padding -->
    <!--app:cardUseCompatPadding="true" 为 Lollipop 及其以上版本增加一个阴影padding内边距-->
    <!--app:cardCornerRadius="8dp" 设置cardView圆角效果-->
    <!--app:cardElevation="10dp" 设置cardView Z轴阴影大小-->
    <!--app:cardMaxElevation="6dp" 设置cardView Z轴最大阴影-->
    <!--app:contentPadding="10dp" 设置内容的内边距-->
    <!--app:contentPaddingBottom="12dp" 设置内容的底部内边距-->
    <!--app:contentPaddingLeft="12dp" 设置内容的左边内边距-->
    <!--app:contentPaddingRight="12dp" 设置内容的右边内边距-->
    <!--app:contentPaddingTop="12dp" 设置内容的顶部内边距-->
    <android.support.v7.widget.CardView

       android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_marginTop="20dp"
        app:cardBackgroundColor="@color/colorPrimary"
        app:cardPreventCornerOverlap="false"
        app:cardUseCompatPadding="true"
        app:cardCornerRadius="8dp"
        app:contentPadding="10dp"
        android:clickable="true"
        android:foreground="?attr/selectableItemBackground"
        app:cardElevation="10dp">

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值