Android CardView属性和使用总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lkjfyy/article/details/81428802

CardView的使用:

如果不知道要依赖的cardview的版本,可以通过以下操作添加依赖:

1、鼠标放在要添加依赖的module上,右键选择Open Module Settings,如图1:

图1

 2、在Module Settings中按图2进行操作:

图2

 点击OK后等待building完成即可。

CardView属性介绍:

Google官方对CardView的一句话解释为:带有阴影背景和圆角的FrameLayout。

下面是CardView的一些常用属性:

<resources>
    <declare-styleable name="CardView">
        <!-- Background color for CardView. -->
        <!-- 设置背景色 -->
        <attr name="cardBackgroundColor" format="color" />
        <!-- Corner radius for CardView. -->
        <!-- 设置圆角大小 -->
        <attr name="cardCornerRadius" format="dimension" />
        <!-- Elevation for CardView. -->
        <!-- 设置Z轴阴影高度 -->
        <attr name="cardElevation" format="dimension" />
        <!-- Maximum Elevation for CardView. -->
        <!-- 设置Z轴阴影最大高度 -->
        <attr name="cardMaxElevation" format="dimension" />
        <!-- Add padding in API v21+ as well to have the same measurements with previous versions. -->
        <!-- 设置内边距,v21+的版本和之前的版本仍旧具有一样的计算方式 -->
        <attr name="cardUseCompatPadding" format="boolean" />
        <!-- Add padding to CardView on v20 and before to prevent intersections between the Card content and rounded corners. -->
        <!-- 在v20和之前的版本中添加内边距,这个属性是为了防止卡片内容和边角的重叠 -->
        <attr name="cardPreventCornerOverlap" format="boolean" />
        <!-- 下面是卡片边界距离内部的距离-->
        <!-- Inner padding between the edges of the Card and children of the CardView. -->
        <attr name="contentPadding" format="dimension" />
        <!-- Inner padding between the left edge of the Card and children of the CardView. -->
        <attr name="contentPaddingLeft" format="dimension" />
        <!-- Inner padding between the right edge of the Card and children of the CardView. -->
        <attr name="contentPaddingRight" format="dimension" />
        <!-- Inner padding between the top edge of the Card and children of the CardView. -->
        <attr name="contentPaddingTop" format="dimension" />
        <!-- Inner padding between the bottom edge of the Card and children of the CardView. -->
        <attr name="contentPaddingBottom" format="dimension" />
    </declare-styleable>
</resources>

下面,我们先通过一些具体的例子来看下CardView的点击水波纹(Ripple)效果(5.0以上包含Android5.0):

图3 (无foreground)
图4 5.0以上(有foreground)
图5 5.0以上(有foreground)
图6 5.0以上(有foreground)
图7 5.0以下(有foreground)
图8 5.0以下(有foreground)

由图3:只要不设置foreground属性,就不会显示Ripple效果;图4和图5分别是Android5.0及以上系统版本设置了系统自带的点击效果;图6是Android5.0及以上系统版本自定义了foreground来实现Ripple效果;图7和图8分别是Android5.0以下使用系统自带的点击效果和自定义foreground来实现Ripple效果,其实可以看出Android5.0以下并没有Ripple效果

布局部分关键代码如下: 

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="15dp"
    tools:context=".CardViewActivity">
    <android.support.v7.widget.CardView
        android:id="@+id/card_view"
        tools:targetApi="lollipop"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:clickable="true"
        app:cardCornerRadius="4dp"
        app:cardUseCompatPadding="false"
        app:cardPreventCornerOverlap="false"
        android:stateListAnimator="@drawable/lift_on_touch"
        android:foreground="?android:attr/selectableItemBackgroundBorderless">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content" 
                android:src="@drawable/dog"
                android:scaleType="centerCrop"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="4dp"
                android:text="CardView测试"
                android:layout_alignParentBottom="true"
                android:background="#80000000"
                android:textColor="#ffffff"/>
        </RelativeLayout>
    </android.support.v7.widget.CardView>
</LinearLayout>

如果直接设置CardView的android:background="@drawable/item_selector"属性是没有效果的。可以通过设置CardView的android:foreground=""属性来设置CardView的点击Ripple效果。可以选择系统自带的点击效果,也可以通过自定义来实现你想要的点击效果

系统自带的效果有两种可供选择:

1、android:background="?android:attr/selectableItemBackground"波纹有边界

2、android:background="?android:attr/selectableItemBackgroundBorderless"波纹超出边界

其中第2种方法需要指定版本为Android5.0,即上面布局文件中的 tools:targetApi="lollipop"。

这样设置以后,在Android5.0以上的设备上有点击有波纹效果,Android5.0以下无波纹,只有前景色变化 

自定义CardView点击Ripple效果

需要分为两种情况,Android5.0及以上和Android5.0以下

Android5.0(版本V21)及以上可以直接使用ripple来设置,效果如图6,关于Ripple的更多使用方法,网上有很多,这里不再介绍:

drawable-v21/card_view_foreground.xml:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#e619c24f">
    <item android:id="@android:id/mask" android:drawable="@color/colorAccent"/>
</ripple>

Android5.0以下,直接使用selector来设置就行,其实只是前景色变化,并没有Ripple效果,效果如图8:

drawable/card_view_foreground.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <solid android:color="#33ed2b0d" />
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#330aa2ff" />
        </shape>
    </item>
</selector>

 CardViewZ轴阴影padding

Google在Android5.0后引入了 Material Design 设计中的阴影(Elevation)和 Z 轴位移。在低版本(Android5.0以前)使用CardView时,系统会给 CardView 加入一个 Elevation 兼容(即 XML 中的 app:cardElevation 和 Java 代码中的 setCardElevation),这也导致了以Android5.0为分界线的不同系统上CardView的尺寸大小不同。

为了解决这个问题,有两种方法:

1、使用 setUseCompatPadding 属性,设置为true(默认值为false),让CardView在不同系统中使用相同的padding值;

2、使用不同API版本的dimension资源适配(也就是借助values和values-21文件夹中不同的dimens.xml文件):

  1. 创建 /res/value 和 /res/value-v21 资源文件夹于项目对应 Module 目录下,前者放置旧版本/通用的资源文件(了解的可以跳过),后者放置 21 及更高 SDK 版本的资源文件。
  2. 在 value 内的 dimen.xml 创建一个 Dimension (<dimen> 属性),随便命个名(如 xxx_card_margin)并填入数值 0dp。
  3. 接着在 value-v21 文件夹内的 dimen.xml 创建名字相同的 Dimension,并填入你期望的预留边距(一般和 CardElevation 阴影大小相同)
  4. 最后,在你布局中的 CardView 中设置android:layout_margin="@dimen/xxx_card_margin"

 圆角覆盖

在Android5.0之前,CardView不会裁剪内容元素以满足圆角需求,而是使用添加padding的替代方案,从而使内容元素不会覆盖CardView的圆角。而控制这个行为的属性就是cardPreventCornerOverlap,默认值为true。该属性的设置在Android5.0及以上版本的系统中没有任何影响,除非cardUseCompatPadding的值为true。下图是在Android5.0版本之前不同cardPreventCornerOverlap值的效果对比图(左false,右true):

图9
图10

显然,默认值下自动添加padding的方式不可取,所以需要设置该属性值为false。

lift-on-touch

根据官网 Material motion 部分对交互动作规范的指导,Cards、Button等视图应该有一个触摸抬起(lift-on-touch)的交互效果,也就是在三维立体空间上的Z轴发生位移,从而产生一个阴影加深的效果,与Ripple效果共同使用,官网给了一个很好的示例图:

图11

 实现这个效果也很简单,可以在 res/drawable 目录下建立一个 lift_on_touch.xml 文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="true" android:state_pressed="true">
        <set>
            <objectAnimator 
                android:duration="@android:integer/config_shortAnimTime" 
                android:propertyName="translationZ" 
                android:valueTo="6dp" 
                android:valueType="floatType" />
        </set>
    </item>
    <item>
        <set>
            <objectAnimator 
                android:duration="@android:integer/config_shortAnimTime" 
                android:propertyName="translationZ" 
                android:valueTo="0" 
                android:valueType="floatType" />
        </set>
    </item>
</selector>

即通过属性动画动态改变translationZ值,沿着Z轴,从0dp到6dp变化。然后将其赋值给 android:stateListAnimator 属性即可。由于 stateListAnimator 属性只适用于Lollipop及以上版本,为了隐藏xml中的版本警告,可以指定 tools:targetApi="lollipop" 。

关于这个功能,需要补充说明一点。这里的 lift_on_touch.xml ,严格意义上来讲,属于anim资源,同时适用于API 21及以上版本,所以按道理上来讲应该将其放置在 res/anim-v21 目录下,然后使用 @anim/lift_on_touch 赋值给 stateListAnimator 属性,而不是例子中的 @drawable/lift_on_touch 方法。但是放置在 res/anim-v21 目录下会产生一个“错误”提示:

XML file should be in either “animator” or “drawable”,not “anim”

虽然这个“错误”不影响编译运行,但是对于追求完美主义的程序员们来说还是碍眼,所以本例中我选择将其放在了 res/drawable 目录下,大家可以自行斟酌使用。

CardView总结

CardView还有一些其他属性可供使用,比如 cardElevation 设置阴影大小, contentPadding 代替普通 android:padding 属性等,比较基础,本文就不一一介绍了,大家可以在官网上参考学习。从上面的介绍可以看出,在使用CardView时基本上都会用到一些标准配置的属性,我们可以借助style属性,将其封装到 styles.xml 文件中,统一管理,比如:

<style name="AppCardView" parent="@style/CardView.Light">
 <item name="cardPreventCornerOverlap">false</item>
 <item name="cardUseCompatPadding">true</item>
 <item name="android:foreground">?attr/selectableItemBackground</item>
 <item name="android:stateListAnimator" tools:targetApi="lollipop">@anim/lift_up</item>
 ......
</style>

抱怨一句,这CSDN的排版是真的无语,调好一发布又是这种样子了,无奈 

参考文章:http://www.open-open.com/lib/view/open1476847497671.html

猜你喜欢

转载自blog.csdn.net/lkjfyy/article/details/81428802