**前言:前面写了一博客 Android订单流程view(超简单!)
其中用到了(CardView),之前也用过,很爽!!所以对于CardView其实很早就想去研究一下它了,于是就有了这篇博客了,写这篇博客的目的呢,主要是属性一下google的工程师们是怎么封装一个控件的,整个过程下来,还是学习到了挺多的知识的,于是打算把我学到的一些东西分享出来,算是当作学习笔记了。**
那么CardView是干什么的呢?
想必有些小伙伴对于它也并不陌生。CardView是v7包中的组件(ViewGroup),主要用来设置布局的边框为圆角、z轴的偏移量(这个是5.0以后才有的概念,也就是阴影的效果)。看一下它的效果:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.yasin.round.MainActivity"
android:orientation="vertical"
>
<com.yasin.round.card.RoundView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:backgroundColor="#ff00"
app:conerRadius="10dp"
app:shadowSize="10dp"
app:shadowStartColor="#33000000"
app:shadowEndColor="#22000000"
>
<RelativeLayout
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="200dp"
>
<TextView
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RoundView"
/>
</RelativeLayout>
</com.yasin.round.card.RoundView>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="10dp"
app:cardBackgroundColor="#ff00"
app:cardElevation="10dp"
app:cardCornerRadius="10dp"
>
<TextView
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="v7(CardView)"
/>
</android.support.v7.widget.CardView>
</LinearLayout>
上面的RoundView是我们照着CardView实现出来的。
运行效果:
当然,系统的CardView是没办法修改阴影的颜色的,我们实现的RoundView对它进行了一些小小的修改,使其能支持颜色修改,当然,我也就实现了大体的部分,本篇roundview只是做演示的demo,小伙伴可不要直接拖到项目中用啊~~
废话不多说,我们要开撸了~~~小伙伴跟紧啦!
首先明确下我们的目标:
1、可以实现圆角功能
2、可以设置阴影(z轴的偏移)
看起来很简单,但是我们的代码还是比较多的,不过没关系,我们重点看一下大神们到底是咋写代码的。
首先我们定义一下我们需要用到的属性:
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RoundView">
<!--背景颜色-->
<attr name="backgroundColor" format="color"></attr>
<!--圆角的半径-->
<attr name="conerRadius" format="dimension"></attr>
<!--z轴的偏移量,(阴影的大小)-->
<attr name="shadowSize" format="dimension"></attr>
<!--阴影的起始颜色-->
<attr name="shadowStartColor" format="color"></attr>
<!--阴影的结束颜色-->
<attr name="shadowEndColor" format="color"></attr>
</declare-styleable>
</resources>
定义好了我们的自定义属性后,我们接下来创建一个view叫RoundView去继承FrameLayout,然后初始化我们的控件获取我们的自定义属性:
public class RoundView extends FrameLayout {
/**
* 阴影的起始颜色
*/
private int mShadowStartColor;
/**
* 阴影的结束颜色
*/
private int mShadowEndColor;
/**
* 圆角半径
*/
private float mRadius;
/**
* 阴影的起始颜色
*/
private float mElevation;
/**
* 控件背景颜色
*/
private ColorStateList mBackgroundColor;
public RoundView(Context context) {
super(context);
initialize(context, null, 0);
}
public RoundView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context, attrs, 0);
}
public RoundView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize(context, attrs, defStyleAttr);
}
private void initialize(Context context, AttributeSet attrs, int defStyleAttr) {
}
}
然后去获取我们的自定义属性:
private void initialize(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundView, defStyleAttr, 0);
//判断是否有背景颜色
if (a.hasValue(R.styleable.RoundView_backgroundColor)) {
mBackgroundColor = a.getColorStateList(R.styleable.RoundView_backgroundColor);
} else {
//获取系统的背景颜色
TypedArray aa = context.obtainStyledAttributes(new int[]{android.R.attr.colorBackground});
//获取系统的背景颜色
int themeBackgroundColor = aa.getColor(0, 0);
//获取背景颜色的hvs值(h色彩、s饱和度、v颜色值)
float[] hsv = new float[3];
Color.colorToHSV(themeBackgroundColor, hsv);
//当饱和度>0.5的时候,我们获取自定义的cardview_dark_background颜色
if (hsv[2] > 0.5) {
mBackgroundColor = ColorStateList.valueOf(getResources().getColor(R.color.cardview_dark_background));
} else {
mBackgroundColor = ColorStateList.valueOf(getResources().getColor(R.color.cardview_dark_background));
}
aa.recycle();
}
mRadius = a.getDimensionPixelSize(R.styleable.RoundView_conerRadius, 0);
mElevation = a.getDimensionPixelSize(R.styleable.RoundView_shadowSize, 0);
mShadowStartColor = a.getColor(R.styleable.RoundView_shadowStartColor, getResources().getColor(R.color.cardview_shadow_start_color));
mShadowEndColor = a.getColor(R.styleable.RoundView_shadowEndColor, getResources().getColor(R.color.cardview_shadow_end_color));
a.recycle();
}
好啦!写到这里我们才完成了最基本的部分,接下来我们需要考虑(兼容android不同版本、提高性能、代码上的高内聚低耦合)等一系列因素了。
考虑到不同的android版本实现圆角、阴影的方式不同的因素,我们应该把具体实现跟我们的roundview分离开来(整个下来有点mvp模式的感觉,你也可以理解为mvp模式吧)。
我们代码中分为三个部分:
- 创建IRoundView来处理roundview的业务逻辑
- RoundRectDrawableWithShadow(drawable)实现具体的功能
- IRoundViewDelegate(相当于roundview的代表)负责IRoundView跟drawable之间的通信。
drawable实现好相关功能->给IRoundView->IRoundView通过IRoundViewDelegate代表类修改roundview的相关属性。
好啦!!知道了大体的框架后,我们就开动了。
首先创建一个IRoundView类:
IRoundView
package com.yasin.round.card;
/**
* Created by leo on 17/3/31.
*/

本文详述了Android CardView的工作原理,并通过创建自定义的RoundView来模仿其功能,包括圆角设置和阴影效果。文章介绍了如何通过IRoundView、RoundRectDrawableWithShadow和IRoundViewDelegate实现圆角和阴影,以及在不同Android版本中优化性能的策略。
最低0.47元/天 解锁文章
7358

被折叠的 条评论
为什么被折叠?



