CircleImageView自定义圆形控件的使用
来源:互联网 发布:博客庄家统计软件 编辑:程序博客网 时间:2024/05/23 21:08
我们可以看到很多app都采用了圆形头像,那么怎么绘制圆形头像才是性能最好?代码复用性最强?也最方便呢?本博主做了一些探究。为了更全面解析,没做得很漂亮,可是这样更助于你理解。本博主不喜欢华而不实的东西。
文章结构:1.利用shape来制作圆形头像(一种死方案,要求是美工愿意配合你) 2.结合一个会导致oom的实现圆形头像方案进行性能分析 3.最优的圆形头像方案
先给效果图大家看看,上面的是用shape实现,下面的是用刚刚所说的最优方案实现
一、利用shape来制作圆形头像(要求是美工愿意配合你)
为什么要求美工配合你呢??因为这个方案是在ImageView直接调用资源文件的,也就是直接用了ImageView的LayoutParams的match_parent模式。不能按照那个圆的大小来适配。
给出代码讲解:drawable文件的shape标签
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <!-- Corner的属性是设置圆角的半径的--> <solid android:color="#FFFFFF" /> <stroke android:width="2dp" android:color="#777777"></stroke> <size android:width="120dp" android:height="120dp" /></shape>
在xml文件中的调用:
<?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:orientation="vertical" tools:context="com.demo.fuzhucheng.someShapesImageview.ImageViewActivity"><!--第一种方案 --> <ImageView android:id="@+id/shapecircle" android:layout_width="150dp" android:layout_height="150dp" android:background="@drawable/activity_circle_circleimageview" android:src="@drawable/activity_imageview_photo" /> <!--最优方案,也就是本文的第三种方案 --><com.demo.fuzhucheng.someShapesImageview.CircleImageview android:id="@+id/mycircle" android:layout_width="180dp" android:layout_height="180dp" android:background="@color/white" android:src="@drawable/timg" app:backgroundHeadColor="@color/yellow" app:circleBorderHeadWidth="5dp" app:ringHeadColor="@color/colorAccent" /></LinearLayout>
二、对一种容易导致OOM的方案进行分析:
给出代码分析:下面这个是别人的代码,由于点评就不给链接的。
public class CircleImageView extends ImageView{ public CircleImageView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { //获得图片的宽度 int width=getWidth(); //获得图片的高度 int height=getHeight(); //短的二分之一作为半径 int radius=height>width?width/2:height/2; //重新定义的一个画布,这一步很关键 Paint mPaint = new Paint(); //抗锯齿 mPaint.setAntiAlias(true); Bitmap bitmap = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888); Canvas bitmapCanvas = new Canvas(bitmap); super.onDraw(bitmapCanvas); //圆形的框 Bitmap cB = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas cCanv = new Canvas(cB); //在控件中间画一个 cCanv.drawCircle(width/ 2, height/ 2, radius, mPaint); canvas.drawBitmap(bitmap, 0.0f, 0.0f, mPaint); //dst是后画的图形 mPaint.setXfermode(new PorterDuffXfermode( PorterDuff.Mode.DST_IN)); //一定要用之前的画布,不然会出现边角是黑色 bitmapCanvas.drawBitmap(cB, 0.0f, 0.0f, mPaint); //给图形加边框 Paint paint =new Paint(); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(5); paint.setColor(Color.BLACK); canvas.drawCircle(width/ 2, height/ 2, radius, paint); }}
分析:在这个方案中,1.因为我们在xml设置的imageview的画布就是占据了一个矩形我们需要重新定义一个画布,而怎么重新定义画布呢,就是重写onDraw然后在他继承父类方法属性前重新定义画布,也就是在super方法前面啦!!可是,这个方法涉及到渲染多层,很容易oom。
2.首先我们要知道画布是怎样一个原理,是基于渲染层的(其实是一个bitmap层存给画布canvas),而这里就先重定义画布一层来作为覆盖掉原来的canvas一层,然后再new了一个canvas进而在里面画一个圆来限定圆形头像来覆盖掉刚刚新建的下面一层canvas。然后利用在super前新建的画布来drawBitmap来画图,进而显示出一个圆形头像(同样经过裁剪)。所以这个涉及渲染多层的方案不可取,而且这段代码设计太过于混乱。
三、最优的圆形头像方案
在这里说明一下整体的思路:1.还是继承ImageView,覆写ImageView,在得到图片后进行处理,没设置图片的时候不处理。 2.使用BitmapShader画圆形的,只要把bitmap传进去,然后把Matrix也传进去作为图片缩放的工具(同样是大图片经过裁剪的方案,无法避免),然后就是set给画笔
下面给出方案的详解,结合代码有详细解释
package com.demo.fuzhucheng.someShapesImageview;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapShader;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.Shader;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.widget.ImageView;import com.demo.fuzhucheng.R;/** * Created by ${符柱成} on 2016/8/21. */public class CircleImageview extends ImageView { private Paint mPaintCircle; //画圆形图像的笔 private Paint mPaintBorder; //画圆形边界的笔 private Paint mPaintBackgroud; //画背景颜色的笔 private BitmapShader mBitmapShader; //图像着色器,可以用来画圆 private Matrix mMatrix; //图片变换处理器-用来缩放图片以适应view控件的大小 private int mWidth; //获得控件宽度 private int mHeight; //获得控件高度 private int mRadius; //中心园的半径 private int mCircleBorderWidth; //边界宽度 private int mCirlcleBorderColor; //边界边框颜色 private int mCircleBackgroudColor; //圆形头像背景色 public CircleImageview(Context context, AttributeSet attrs) { super(context, attrs); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleHead);//将获取的属性转化为我们最先设好的属性 int n = typedArray.getIndexCount(); for (int i = 0; i < n; i++) { int attr = typedArray.getIndex(i); switch (attr) { case R.styleable.CircleHead_circleBorderHeadWidth: mCircleBorderWidth = (int) typedArray.getDimension(attr, 0); break; case R.styleable.CircleHead_ringHeadColor: mCirlcleBorderColor = typedArray.getColor(attr, Color.GREEN); break; case R.styleable.CircleHead_backgroundHeadColor: mCircleBackgroudColor = typedArray.getColor(attr, Color.YELLOW); break; } } init(); } private void init() { //初始化图片变换处理器 mMatrix = new Matrix(); mPaintCircle = new Paint(); mPaintCircle.setAntiAlias(true);//抗锯齿,没有消除锯齿的话,图片变换会很难看的,因为有些像素点会失真 mPaintCircle.setStrokeWidth(12); //设置圆边界宽度 //附加效果设置阴影 this.setLayerType(LAYER_TYPE_SOFTWARE, mPaintCircle); mPaintCircle.setShadowLayer(13.0f, 5.0f, 5.0f, Color.GRAY); //给图形加边框 mPaintBorder = new Paint(); mPaintBorder.setAntiAlias(true); mPaintBorder.setStyle(Paint.Style.STROKE); mPaintBorder.setStrokeWidth(mCircleBorderWidth); mPaintBorder.setColor(mCirlcleBorderColor); //画背景颜色的笔 mPaintBackgroud = new Paint(); mPaintBackgroud.setColor(mCircleBackgroudColor); mPaintBackgroud.setAntiAlias(true); mPaintBackgroud.setStyle(Paint.Style.FILL); } //使用BitmapShader画圆图形 private void setBitmapShader() { //将图片转换成Bitmap Drawable drawable = getDrawable(); BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; Bitmap bitmap = bitmapDrawable.getBitmap(); //将bitmap放进图像着色器,后面两个模式是x,y轴的缩放模式,CLAMP表示拉伸 mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); //初始化图片与view之间伸缩比例,因为比例一般非整数,所以用float,免得精度丢失 float scale = 1.0f;// float scaleX = 1.0f; //将图片的宽度高度的最小者作为图片的边长,用来和view来计算伸缩比例// int bitmapSize = Math.min(bitmap.getWidth(), bitmap.getHeight()); int bitmapSize = Math.min(bitmap.getHeight(), bitmap.getWidth()); // int bitmapSizeX = bitmap.getWidth(); // scaleX = mWidth * 1.0f / bitmapSizeX; /**注意这里,我使用的是图片最长的(就是宽度)来伸缩,那么用这个的话, * 我们就会发现,较短的那边(就是高度)在经过Matrix的拉伸后会发现失真,强行地被拉长, * 一、因为图片为了适应最长的那边可以完全在view上展示,把长的给压缩了,而短的比长的那边短,所以要强行拉伸,那么就会导致短的这边被拉伸时候失真 *二、因为图像的变换是针对每一个像素点的,所以有些变换可能发生像素点的丢失, * 这里需要使用Paint.setAnitiAlias(boolean)设置来消除锯齿,这样图片变换后的效果会好很多。 */ //计算缩放比例,view的大小和图片的大小比例 scale = mWidth * 1.0f / bitmapSize; //利用这个图像变换处理器,设置伸缩比例,长宽以相同比例伸缩 mMatrix.setScale(scale, scale); //给那个图像着色器设置变换矩阵,绘制时就根据view的size,设置图片的size //使图片的较小的一边缩放到view的大小一致,这样就可以避免图片过小导致CLAMP拉伸模式或过大导致显示不全 mBitmapShader.setLocalMatrix(mMatrix); //为画笔套上一个Shader的笔套 mPaintCircle.setShader(mBitmapShader); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); /** * 在这里设置高度宽度,以设置的较小值为准,防止不成圆 */ mWidth = getWidth(); mHeight = getHeight(); int mCircleSize = Math.min(mHeight, mWidth); //圆的半径短的二分之一作为半径 mRadius = mCircleSize / 2 - mCircleBorderWidth; } /** * 我们可以知道,如果我们直接用imageview然后引用shape弄成圆形的话,意味着我们在这个imageview的逻辑只能写在fragment等等里面了,而很难去进行逻辑的分层.。而且!!只能用矢量图并且美工要配合你 * 因此我们重写imageview就是为了更好地封装好点击imageview的逻辑 * 一、因为我们在xml设置的imageview的画布就是占据了一个矩形我们需要重新定义一个画布 * 而怎么重新定义画布呢,就是重写onDraw然后在他继承父类方法属性前重新定义画布,也就是在super方法前面啦!!可是,这个方法涉及到渲染多层,很容易oom * 二、然而我们将用另一种方法,使用BitmapShader画圆形的,只要把bitmap传进去,然后把Matrix也传进去作为图片缩放的工具 */ /* * Canvas理解成系统提供给我们的一块内存区域(但实际上它只是一套画图的API,真正的内存是下面的Bitmap), *而且它还提供了一整套对这个内存区域进行操作的方法,所有的这些操作都是画图API。 *也就是说在这种方式下我们已经能一笔一划或者使用Graphic来画我们所需要的东西了,要画什么要显示什么都由我们自己控制。 */ @Override protected void onDraw(Canvas canvas) { //这里注释掉onDraw是为了不绘制原来的画布,如果使用的话就意味着又是渲染一层,就会像第二个方案那样容易OOM // super.onDraw(canvas); if (getDrawable() != null) { setBitmapShader(); canvas.drawRect(0, 0, mWidth, mHeight, mPaintBackgroud);//直接构造,画背景的,为什么画背景?因为画布是方的,市面上所有圆形头像都是没有直接处理边角的,而是用Framelayout来进去覆盖,所以这里定义个背景色告诉大家,当然也封装好给大家使用 canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius, mPaintCircle); //画边框 canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius + mCircleBorderWidth / 2, mPaintBorder); } else { //如果在xml中这个继承ImageView的类没有被set图片就用默认的ImageView方案咯 super.onDraw(canvas); } }}
还有在自定义属性的代码,因为本博文不只是解析嘛,顺便封装给大家使用。可以看到有三个属性,边框宽度,背景颜色以及圆环颜色
<declare-styleable name="CircleHead"> <attr name="circleBorderHeadWidth" format="dimension" /> <attr name="ringHeadColor" format="color" /> <attr name="backgroundHeadColor" format="color" /> </declare-styleable>
至于调用的方式就在第一种方案中已经给出就不重复贴代码了。
另外大家有没有留意到我写的那两个方案以及别人的方案(本文第二个方案)都是有边角没处理的?因为画布是方的,市面上所有圆形头像都是没有直接处理边角的,而是用Framelayout来进去覆盖,所以这里定义个背景色告诉大家,当然也封装好给大家使用。
文/JackFrost_fuzhu(简书作者)
原文链接:http://www.jianshu.com/p/a12fc72e960e
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <!-- Corner的属性是设置圆角的半径的--> <solid android:color="#FFFFFF" /> <stroke android:width="2dp" android:color="#777777"></stroke> <size android:width="120dp" android:height="120dp" /></shape>
<?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:orientation="vertical" tools:context="com.demo.fuzhucheng.someShapesImageview.ImageViewActivity"><!--第一种方案 --> <ImageView android:id="@+id/shapecircle" android:layout_width="150dp" android:layout_height="150dp" android:background="@drawable/activity_circle_circleimageview" android:src="@drawable/activity_imageview_photo" /> <!--最优方案,也就是本文的第三种方案 --><com.demo.fuzhucheng.someShapesImageview.CircleImageview android:id="@+id/mycircle" android:layout_width="180dp" android:layout_height="180dp" android:background="@color/white" android:src="@drawable/timg" app:backgroundHeadColor="@color/yellow" app:circleBorderHeadWidth="5dp" app:ringHeadColor="@color/colorAccent" /></LinearLayout>
public class CircleImageView extends ImageView{ public CircleImageView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { //获得图片的宽度 int width=getWidth(); //获得图片的高度 int height=getHeight(); //短的二分之一作为半径 int radius=height>width?width/2:height/2; //重新定义的一个画布,这一步很关键 Paint mPaint = new Paint(); //抗锯齿 mPaint.setAntiAlias(true); Bitmap bitmap = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888); Canvas bitmapCanvas = new Canvas(bitmap); super.onDraw(bitmapCanvas); //圆形的框 Bitmap cB = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas cCanv = new Canvas(cB); //在控件中间画一个 cCanv.drawCircle(width/ 2, height/ 2, radius, mPaint); canvas.drawBitmap(bitmap, 0.0f, 0.0f, mPaint); //dst是后画的图形 mPaint.setXfermode(new PorterDuffXfermode( PorterDuff.Mode.DST_IN)); //一定要用之前的画布,不然会出现边角是黑色 bitmapCanvas.drawBitmap(cB, 0.0f, 0.0f, mPaint); //给图形加边框 Paint paint =new Paint(); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(5); paint.setColor(Color.BLACK); canvas.drawCircle(width/ 2, height/ 2, radius, paint); }}
package com.demo.fuzhucheng.someShapesImageview;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapShader;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.Shader;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.widget.ImageView;import com.demo.fuzhucheng.R;/** * Created by ${符柱成} on 2016/8/21. */public class CircleImageview extends ImageView { private Paint mPaintCircle; //画圆形图像的笔 private Paint mPaintBorder; //画圆形边界的笔 private Paint mPaintBackgroud; //画背景颜色的笔 private BitmapShader mBitmapShader; //图像着色器,可以用来画圆 private Matrix mMatrix; //图片变换处理器-用来缩放图片以适应view控件的大小 private int mWidth; //获得控件宽度 private int mHeight; //获得控件高度 private int mRadius; //中心园的半径 private int mCircleBorderWidth; //边界宽度 private int mCirlcleBorderColor; //边界边框颜色 private int mCircleBackgroudColor; //圆形头像背景色 public CircleImageview(Context context, AttributeSet attrs) { super(context, attrs); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleHead);//将获取的属性转化为我们最先设好的属性 int n = typedArray.getIndexCount(); for (int i = 0; i < n; i++) { int attr = typedArray.getIndex(i); switch (attr) { case R.styleable.CircleHead_circleBorderHeadWidth: mCircleBorderWidth = (int) typedArray.getDimension(attr, 0); break; case R.styleable.CircleHead_ringHeadColor: mCirlcleBorderColor = typedArray.getColor(attr, Color.GREEN); break; case R.styleable.CircleHead_backgroundHeadColor: mCircleBackgroudColor = typedArray.getColor(attr, Color.YELLOW); break; } } init(); } private void init() { //初始化图片变换处理器 mMatrix = new Matrix(); mPaintCircle = new Paint(); mPaintCircle.setAntiAlias(true);//抗锯齿,没有消除锯齿的话,图片变换会很难看的,因为有些像素点会失真 mPaintCircle.setStrokeWidth(12); //设置圆边界宽度 //附加效果设置阴影 this.setLayerType(LAYER_TYPE_SOFTWARE, mPaintCircle); mPaintCircle.setShadowLayer(13.0f, 5.0f, 5.0f, Color.GRAY); //给图形加边框 mPaintBorder = new Paint(); mPaintBorder.setAntiAlias(true); mPaintBorder.setStyle(Paint.Style.STROKE); mPaintBorder.setStrokeWidth(mCircleBorderWidth); mPaintBorder.setColor(mCirlcleBorderColor); //画背景颜色的笔 mPaintBackgroud = new Paint(); mPaintBackgroud.setColor(mCircleBackgroudColor); mPaintBackgroud.setAntiAlias(true); mPaintBackgroud.setStyle(Paint.Style.FILL); } //使用BitmapShader画圆图形 private void setBitmapShader() { //将图片转换成Bitmap Drawable drawable = getDrawable(); BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; Bitmap bitmap = bitmapDrawable.getBitmap(); //将bitmap放进图像着色器,后面两个模式是x,y轴的缩放模式,CLAMP表示拉伸 mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); //初始化图片与view之间伸缩比例,因为比例一般非整数,所以用float,免得精度丢失 float scale = 1.0f;// float scaleX = 1.0f; //将图片的宽度高度的最小者作为图片的边长,用来和view来计算伸缩比例// int bitmapSize = Math.min(bitmap.getWidth(), bitmap.getHeight()); int bitmapSize = Math.min(bitmap.getHeight(), bitmap.getWidth()); // int bitmapSizeX = bitmap.getWidth(); // scaleX = mWidth * 1.0f / bitmapSizeX; /**注意这里,我使用的是图片最长的(就是宽度)来伸缩,那么用这个的话, * 我们就会发现,较短的那边(就是高度)在经过Matrix的拉伸后会发现失真,强行地被拉长, * 一、因为图片为了适应最长的那边可以完全在view上展示,把长的给压缩了,而短的比长的那边短,所以要强行拉伸,那么就会导致短的这边被拉伸时候失真 *二、因为图像的变换是针对每一个像素点的,所以有些变换可能发生像素点的丢失, * 这里需要使用Paint.setAnitiAlias(boolean)设置来消除锯齿,这样图片变换后的效果会好很多。 */ //计算缩放比例,view的大小和图片的大小比例 scale = mWidth * 1.0f / bitmapSize; //利用这个图像变换处理器,设置伸缩比例,长宽以相同比例伸缩 mMatrix.setScale(scale, scale); //给那个图像着色器设置变换矩阵,绘制时就根据view的size,设置图片的size //使图片的较小的一边缩放到view的大小一致,这样就可以避免图片过小导致CLAMP拉伸模式或过大导致显示不全 mBitmapShader.setLocalMatrix(mMatrix); //为画笔套上一个Shader的笔套 mPaintCircle.setShader(mBitmapShader); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); /** * 在这里设置高度宽度,以设置的较小值为准,防止不成圆 */ mWidth = getWidth(); mHeight = getHeight(); int mCircleSize = Math.min(mHeight, mWidth); //圆的半径短的二分之一作为半径 mRadius = mCircleSize / 2 - mCircleBorderWidth; } /** * 我们可以知道,如果我们直接用imageview然后引用shape弄成圆形的话,意味着我们在这个imageview的逻辑只能写在fragment等等里面了,而很难去进行逻辑的分层.。而且!!只能用矢量图并且美工要配合你 * 因此我们重写imageview就是为了更好地封装好点击imageview的逻辑 * 一、因为我们在xml设置的imageview的画布就是占据了一个矩形我们需要重新定义一个画布 * 而怎么重新定义画布呢,就是重写onDraw然后在他继承父类方法属性前重新定义画布,也就是在super方法前面啦!!可是,这个方法涉及到渲染多层,很容易oom * 二、然而我们将用另一种方法,使用BitmapShader画圆形的,只要把bitmap传进去,然后把Matrix也传进去作为图片缩放的工具 */ /* * Canvas理解成系统提供给我们的一块内存区域(但实际上它只是一套画图的API,真正的内存是下面的Bitmap), *而且它还提供了一整套对这个内存区域进行操作的方法,所有的这些操作都是画图API。 *也就是说在这种方式下我们已经能一笔一划或者使用Graphic来画我们所需要的东西了,要画什么要显示什么都由我们自己控制。 */ @Override protected void onDraw(Canvas canvas) { //这里注释掉onDraw是为了不绘制原来的画布,如果使用的话就意味着又是渲染一层,就会像第二个方案那样容易OOM // super.onDraw(canvas); if (getDrawable() != null) { setBitmapShader(); canvas.drawRect(0, 0, mWidth, mHeight, mPaintBackgroud);//直接构造,画背景的,为什么画背景?因为画布是方的,市面上所有圆形头像都是没有直接处理边角的,而是用Framelayout来进去覆盖,所以这里定义个背景色告诉大家,当然也封装好给大家使用 canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius, mPaintCircle); //画边框 canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius + mCircleBorderWidth / 2, mPaintBorder); } else { //如果在xml中这个继承ImageView的类没有被set图片就用默认的ImageView方案咯 super.onDraw(canvas); } }}
<declare-styleable name="CircleHead"> <attr name="circleBorderHeadWidth" format="dimension" /> <attr name="ringHeadColor" format="color" /> <attr name="backgroundHeadColor" format="color" /> </declare-styleable>
原文链接:http://www.jianshu.com/p/a12fc72e960e
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
0 0
- CircleImageView自定义圆形控件的使用
- CircleImageView自定义圆形控件的使用
- CircleImageView自定义圆形控件的使用
- binbinyang-----CircleImageView自定义圆形控件的使用
- CircleImageView自定义圆形控件的使用
- android开源系列:CircleImageView自定义圆形控件的使用
- android开源系列:CircleImageView自定义圆形控件的使用
- android开源系列:CircleImageView自定义圆形控件的使用
- android开源系列:CircleImageView自定义圆形控件的使用
- android开源系列:CircleImageView自定义圆形控件的使用
- android开源系列:CircleImageView自定义圆形控件的使用
- android开源系列:CircleImageView自定义圆形控件的使用
- android开源系列:CircleImageView自定义圆形控件的使用
- android开源系列:CircleImageView自定义圆形控件的使用
- 自定义圆形圆形控件CircleImageview
- CircleImageView自定义圆形控件的使
- Android圆形图片控件CircleImageView的使用
- android 圆形头像—— android开源系列:CircleImageView自定义圆形控件的使用
- 经典进程间通信之无名管道和有名管道
- [LeetCode]2. Add Two Numbers
- tomcat部署oracle数据库
- Java静态检查实现机制比较
- ExploitExercises_Nebula_Level04
- CircleImageView自定义圆形控件的使用
- 167. Two Sum II - Input array is sorted
- 常用表单的正则表达式
- 超级表格企业版收费即将进行政策调整
- 十大编程算法助程序员走上高手之路
- 蓝桥杯BASIC_23(芯片测试)
- JAVA中字符串长度与字节
- java的初始化顺序
- C++ 中error: ‘exit’ was not declared in this scope 的解决方法