(三十六)CardView 使用及源码分析
来源:互联网 发布:多线程cpu优化 编辑:程序博客网 时间:2024/06/02 06:38
版权声明:本文为博主原创文章,未经博主允许不得转载。
本文纯个人学习笔记,由于水平有限,难免有所出错,有发现的可以交流一下。
一、使用
1.demo
CardView 的使用很简单,直接上个 demo 看一下。
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout 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" tools:context="com.xiaoyue.cardview.MainActivity"> <android.support.v7.widget.CardView android:layout_width="wrap_content" android:layout_height="wrap_content" app:cardCornerRadius="15dp"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/a"/> </android.support.v7.widget.CardView></android.support.constraint.ConstraintLayout>
直接在布局文件中使用即可。
效果1:
这是在安卓 5.0 以上的系统,在安卓 5.0 以下的系统显示的效果不一样。
效果2:
在布局文件中,给 CardView 设置 app:cardCornerRadius (圆角)属性,但是实际生效的是 CardView 下的子控件 ImageView。
2.使用文字
对比上面两个效果图,可以发现,在 5.0 以下系统,CardView 下边沿有一个默认的 Padding,在 5.0 以上是没有的。
这时候如果使用文字的话会导致文字部分被遮挡住。
5.0 以上效果:
5.0 以下效果:
这时候就需要对 CardView 使用 contentPadding 进行边距的设置。
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout 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" tools:context="com.xiaoyue.cardview.MainActivity"> <android.support.v7.widget.CardView android:layout_width="400dp" android:layout_height="200dp" app:cardCornerRadius="25dp" app:contentPadding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/app_name" android:textSize="20dp"/> </android.support.v7.widget.CardView></android.support.constraint.ConstraintLayout>
效果:
3.其他属性
● android:cardCornerRadius ○ 在xml文件中设置card圆角的大小 ● CardView.setRadius ○ 在代码中设置card圆角的大小 ● android:cardBackgroundColor ○ 在xml文件中设置card背景颜色 ● android:elevation ○ 在xml文件中设置阴影的大小 ● card_view:cardElevation ○ 在xml文件中设置阴影的大小 ● card_view:cardMaxElevation ○ 在xml文件中设置阴影最大高度 ● card_view:cardCornerRadius ○ 在xml文件中设置卡片的圆角大小 ● card_view:contentPadding ○ 在xml文件中设置卡片内容于边距的间隔 ● card_view:contentPaddingBottom ○ 在xml文件中设置卡片内容于下边距的间隔 ● card_view:contentPaddingTop ○ 在xml文件中设置卡片内容于上边距的间隔 ● card_view:contentPaddingLeft ○ 在xml文件中设置卡片内容于左边距的间隔 ● card_view:contentPaddingRight ○ 在xml文件中设置卡片内容于右边距的间隔 ● card_view:contentPaddingStart ○ 在xml文件中设置卡片内容于边距的间隔起始 ● card_view:contentPaddingEnd ○ 在xml文件中设置卡片内容于边距的间隔终止 ● card_view:cardUseCompatPadding ○ 在xml文件中设置内边距,V21+的版本和之前的版本仍旧具有一样的计算方式 ● card_view:cardPreventConrerOverlap ○ 在xml文件中设置内边距,在V20和之前的版本中添加内边距,这个属性为了防止内容和边角的重叠
二、源码
public class CardView extends FrameLayout { private static final int[] COLOR_BACKGROUND_ATTR = {android.R.attr.colorBackground}; 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(); } ... private final CardViewDelegate mCardViewDelegate = new CardViewDelegate() { ... }}
首先,CardView 继承于 FrameLayout ,拥有 FrameLayout 的特性。CardView 跟 AppCompat 使用了一样的机制,根据版本进行判断,去实例化不同的实现类,以及使用代理进行对象的操作。
这边从设置圆角开始分析,为什么属性添加在 CardView 却作用于 CardView 下的子控件。
CardView 的构造函数调用了初始化方法 initialize()。
initialize:
private void initialize(Context context, AttributeSet attrs, int defStyleAttr) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CardView, defStyleAttr, R.style.CardView); ... IMPL.initialize(mCardViewDelegate, context, backgroundColor, radius, elevation, maxElevation); }
initialize 进行了 xml 设置的属性获取,最终调用 CardViewImpl 的 initialize 方法,上面说了,CardViewImpl 会根据版本去实例化不同的实现类。
CardViewApi21Impl
class CardViewApi21Impl implements CardViewImpl { @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); } ...}
在安卓 5.0 以上的时候,实例化了 CardViewApi21Impl 对象,CardViewApi21Impl 的 initialize 方法有一个 RoundRectDrawable ,并把这个设置为 CardView 的 Background。我们看一下 RoundRectDrawable 。
RoundRectDrawable :
class RoundRectDrawable extends Drawable { ... @Override public void draw(Canvas canvas) { final Paint paint = mPaint; final boolean clearColorFilter; if (mTintFilter != null && paint.getColorFilter() == null) { paint.setColorFilter(mTintFilter); clearColorFilter = true; } else { clearColorFilter = false; } canvas.drawRoundRect(mBoundsF, mRadius, mRadius, paint); if (clearColorFilter) { paint.setColorFilter(null); } } ... /** * Ensures the tint filter is consistent with the current tint color and * mode. */ private PorterDuffColorFilter createTintFilter(ColorStateList tint, PorterDuff.Mode tintMode) { if (tint == null || tintMode == null) { return null; } final int color = tint.getColorForState(getState(), Color.TRANSPARENT); return new PorterDuffColorFilter(color, tintMode); }}
RoundRectDrawable 的 draw 方法设置了一个 setColorFilter,这个 ColorFilter 是通过 createTintFilter 获取到的,然后调用 canvas.drawRoundRect 就会跟原先的背景进行混合,tintMode 就是混合模式 PorterDuff.Mode.SRC_IN。所以会产生图片是圆角的效果。
(混合模式具体链接:http://blog.csdn.net/qq_18983205/article/details/72810681)
再查看 CardViewApi17Impl ,这个实现类没有 RoundRectDrawable 这个东西,所以不能使图片变成圆角。
- (三十六)CardView 使用及源码分析
- CardView使用及属性
- 卡片式控件CardView&源码分析
- 卡片式控件CardView&源码分析
- Redis源码分析(三十六)--- Redis中的11大优秀设计
- Redis源码分析(三十六)--- Redis中的11大优秀设计
- Weevely使用及源码分析(一)
- Weevely使用及源码分析(二)
- Weevely使用及源码分析(三)
- RecyclerView的使用及配合CardView使用
- SpoolDirectorySource使用及源码分析
- SQLiteOpenHelper使用及源码分析
- HandlerThread源码分析及使用
- IntentService使用及源码分析
- AsyncTask使用及源码分析
- ArrayBlockingQueue源码分析及使用
- swagger使用及源码分析
- ArrayBlockingQueue源码分析及使用
- 简易计算器
- 安装交叉编译工具链
- 一道很有趣的面试题——————SQL
- SSM环境搭建(一)
- Node.js —— 使用http模块创建Web服务器
- (三十六)CardView 使用及源码分析
- 日历
- img标签不能访问本地图片
- 一个自学的小白----------------------Python while练习
- workspace\.metadata\.plugins\org.eclipse.wst.server.core
- ACdream 1064 完美数【数位DP】
- iptables备份和恢复、firewalld的9个zone和操作
- codevs1011数的计算
- jerseycom.sun.jersey.api.client.UniformInterfaceException