转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/47258639
本文分为三大部分:
- CircleImageView的使用
- CircleImageView源码分析
- Android自定义View总结
CircleImageView项目源码下载:
https://github.com/hdodenhof/CircleImageView
打开源码会发现主要就是一个继承了ImageView 的类——CircleImageView .java,代码优雅精致,效果很nice。下面会进行源码分析,让我加深了不少Canvas、BitmapShader、Matrix相关知识。
CircleImageView的使用
我这里一步步展示使用步骤,记录下当时遇到的问题。
- 按照上面的地址下载,项目文件名CircleImageView-master。目录下的circleimageview为库文件,sample为官方demo,使用fragment比较繁琐。这里我自己新建demo学会使用。
新建一个Android项目CircleImageViewDemo_1,复制上一步circleimageview文件夹里的CircleImageView.java到CircleImageViewDemo_1中。
CircleImageView.java地址:
CircleImageView-master\circleimageview\src\main\java\de\hdodenhof\circleimageview
项目src中:
此时会发现CircleImageView.java里报错,出错为没有R.styleable.CircleImageView。这是因为我们缺少自定义View的属性attrs.xml。在CircleImageView-master中找到attrs.xml并复制到项目里的res/values下。错误消失。
attrs.xml地址:
CircleImageView-master\circleimageview\src\main\res\values
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircleImageView">
<attr name="border_width" format="dimension" />
<attr name="border_color" format="color" />
<attr name="border_overlay" format="boolean" />
</declare-styleable>
</resources>
4 接下来就要在activity_main.xml里使用CircleImageView了。我仿照官方demo进行layout布局,同时引用官方图片。
<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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.circleimageviewdemo_1.MainActivity" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="@dimen/base_padding"
android:background="@color/light">
<com.example.library.CircleImageView
android:layout_width="160dp"
android:layout_height="160dp"
android:layout_centerInParent="true"
android:src="@drawable/hugh"
app:border_width="2dp"
app:border_color="@color/dark" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="@dimen/base_padding"
android:background="@color/dark">
<com.example.library.CircleImageView
android:layout_width="160dp"
android:layout_height="160dp"
android:layout_centerInParent="true"
android:src="@drawable/hugh"
app:border_width="2dp"
app:border_color="@color/light" />
</RelativeLayout>
</LinearLayout>
注意两点:
- 在xml布局文件中,声明我们的自定义View,路径要正确。
com.example.library.CircleImageView
- 一定要引入命名空间,xmlns:app=”http://schemas.android.com/apk/res-auto”,不然无法使用自定义属性。
MainActivity里不用修改,因为我直接在XML里面用src设置了图片,你也可以在MainActivity中用setImageXXX设置。直接运行看效果。
总结下CircleImageView的使用:
- 将CircleImageView.java拷贝到项目工程中
- attrs.xml拷贝到res/values/目录下
- 在布局文件中声明自定义View,一定要引入命名空间xmlns:app=”http://schemas.android.com/apk/res-auto”。
Demo下载:
http://download.csdn.net/detail/zhoubin1992/8956647
CircleImageView源码分析
一直很好奇这个开源库是怎么自定义圆形ImageView,结果最近花了很多功夫进行分析,现在也非常迫切想整理出来,希望能帮到一些人。我也看了网络上的一些源码分析,有些分析是错误的会误导大家,有些说的不详细还是无法理解。
首先我先总结下CircleImageView的主要流程,让大家有个整体把握。然后再一步步进入源码分析。
CircleImageView的主要流程:
1. 首先通过setImageXxx()方法设置图片Bitmap;
2. 进入构造函数CircleImageView()获取自定义参数,以及调用setup()函数;
3. 进入setup()函数(非常关键),进行图片画笔边界画笔(Paint)一些重绘参数初始化:构建渲染器BitmapShader用Bitmap来填充绘制区域,设置样式和内外圆半径计算等,以及调用updateShaderMatrix()函数和 invalidate()函数;
4. 进入updateShaderMatrix()函数,计算缩放比例和平移,设置BitmapShader的Matrix参数等;
5. 触发ondraw()函数完成最终的绘制。使用配置好的Paint先画出绘制内圆形来以后再画边界圆形。
下面来详细分析一下源码:
1. 首先从项目里调用CircleImageView开始分析,我们要么在XML里面用src,要么调用CircleImageView的setImageXXX()方法设置图片。那我们的