android 自定义圆角头像以及使用declare-styleable进行配置属性解析

合集下载

android屏幕圆角实现方法的示例代码

android屏幕圆角实现方法的示例代码

android屏幕圆⾓实现⽅法的⽰例代码现在很多全⾯屏⼿机的屏幕四⾓做成圆的,其圆润的感觉给⼈带来别样的视觉体验。

先来⼀张我⼤锤⼦镇楼(不是⼴告呀,锤⼦没给钱),⼤家来直观感受⼀下圆⾓的魅⼒。

锤⼦.jpg当然这种是硬件上实现的,我怀疑也是⽅的显⽰屏,然后做了个圆⾓遮蔽。

那对于我们这些脸⽅的⼿机,就不能笑嘻嘻的圆⼀回吗?答案是肯定的,no picture say ...效果图(应该能看出来我⽤的是神马⼿机吧)圆⾓实现:那我们就应该思考了,软件层⾯怎样实现这种效果呢。

相信很多朋友⽴马会想到——使⽤悬浮窗。

实现原理:利⽤WindowManager将我们的圆⾓加到屏幕的四个⾓,圆⾓颜⾊设置为⿊⾊,形成视觉圆⾓屏幕。

1.⾃定义圆⾓view很显然,⾸先我们需要实现⼀个形状如下图的圆⾓,怎么做呢?⽤path(不熟悉的⼩伙伴可以百度⼀下哈),这⾥我们以左上⾓为例实现这个圆⾓。

圆⾓// top leftcase Gravity.TOP | Gravity.LEFT:path.moveTo(0.0f, 0.0f);path.lineTo(0.0f, (float) h);path.arcTo(new RectF(0.0f, 0.0f,((float) w) * 2.0f, ((float) h) * 2.0f), 180.0f, 90.0f, true);path.lineTo((float) w, 0.0f);path.lineTo(0.0f, 0.0f);path.close();break;为了能让⽤户⾃定义圆⾓颜⾊,⼤⼩,透明度,各个⾓是否显⽰,我在⾥⾯加了对应的控制变量,当⽤户设置的时候更新view就可以了。

public void setCornerSize(int size){this.cornerSize = size;requestLayout();invalidate();}是不是很简单,这样⼀个圆⾓view就实现了。

自定义view实现圆角图片

自定义view实现圆角图片

自定义view实现圆角图片前两天想实现一个圆角图片的效果,通过网络搜索后找到一些答案。

这里自己再记录一下,加深一下自己的认识和知识理解。

?实现圆角图片的思路是自定义一个ImageView,然后通过Ondraw()重绘的功能,将drawable和一个圆形进行重叠绘制,这样就可以达到圆角的效果了。

?下面开始具体实现圆角图片的过程。

第一步:写自定义属性文件首先我们需要定义一个属性。

在values目录下面新建一个xml文件,这个文件用来自定义一些属性,这样我们就可以写出自己的控件了。

我来简单解释一下,declare-styleable这个标签就是用来自定义属性的,attr标签用来定义具体的属性,format可以指定很多种格式,具体有哪些属性,这里不做过多介绍了,请看博客中的介绍:本来图片修改为圆形,其他地方都是透明2.只是让显示的时候,动态的裁剪到一些部分,然后让图片变圆。

这两种方法的优劣我想大家一眼就能看明白。

直接修改图片,带来的后果是,我如果换了一种方式了,不再是圆角,而是星型,那么我们的图片已经毁掉了,没办法在重用了。

而第二种方式就可以,无论我们换什么样的表现方式,我们是需要换一种裁剪的算法,就可以实现不同的形状的图片了,那么很显然,第二种方法是以不变应万变的。

那么现在,我们选定了第二种方式,那怎么实现呢有人说我们自己写一个类,直接继承自view,然后所有的绘图和大小的计算我们都自己来搞,这样行吗当然可行,但是我们可能是在重复造轮子,因为我们已经有了一个ImageView,而且它里面给我们做了很多关于图片的操作,我们何不继承自ImageView,然后做少量的工作,就可以实现圆角效果呢。

方案确定,好,那我们就开始实现自己的类。

我们定义一个RoundImageView 继承自ImageView?然后两个成员变量,分别对应于自定义属性文件中的BorderRadius和RoundType。

?接下来我们重写构造函数首先是mPaint的初始化,这是一个画刷,用来画图形的,后面会说。

Android-解析自定义view之圆形头像的各类方案

Android-解析自定义view之圆形头像的各类方案

Android-解析自定义view之圆形头像的各类方案我们可以看到很多app都采用了圆形头像,那么怎么绘制圆形头像才是性能最好?代码复用性最强?也最方便呢?本博主做了一些探究。

文章结构:1.利用shape来制作圆形头像(一种死方案,要求是美工愿意配合你) 2.结合一个会导致oom的实现圆形头像方案进行性能分析 3.最优的圆形头像方案一、利用shape来制作圆形头像(要求是美工愿意配合你)为什么要求美工配合你呢??因为这个方案是在ImageView直接调用资源文件的,也就是直接用了ImageView的LayoutParams的match_parent模式。

不能按照那个圆的大小来适配。

给出代码讲解:drawable文件的shape标签<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="/apk/res/android"android:shape="oval"><!-- Corner的属性是设置圆角的半径的--><solid android:color="#FFFFFF" /><strokeandroid:width="2dp"android:color="#777777"></stroke><sizeandroid:width="120dp"android:height="120dp" /></shape>在xml文件中的调用:<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="com.demo.fuzhucheng.someShapesImageview.ImageViewActivity"><!--第一种方案--><ImageViewandroid: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的方案进行分析:给出代码分析:下面这个是别人的代码,由于点评就不给链接的。

Android对控件设置边框样式(边框颜色,圆角)和图片样式(圆角)

Android对控件设置边框样式(边框颜色,圆角)和图片样式(圆角)

Android对控件设置边框样式(边框颜⾊,圆⾓)和图⽚样式(圆⾓)1、设置边框、圆⾓、背景⾊案例在drawable中新建⼀个edge.xml⽂件<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="/apk/res/android"><!-- 这⾥是设置背景⾊--><solid android:color="@color/colorGrey"/><!-- 这⾥是设置为四周也可以单独设置某个位置为圆⾓--><corners android:topLeftRadius="5dp"android:topRightRadius="5dp"android:bottomRightRadius="5dp"android:bottomLeftRadius="5dp"/><!-- 这⾥设置边框 --><stroke android:width="1dp" android:color="#000000"/></shape>Activity页⾯引⽤:android:background="@drawable/edge"如下案例所⽰:<ScrollViewandroid:id="@+id/scrollView2"android:layout_width="0dp"android:layout_height="0dp"android:layout_marginStart="8dp"android:layout_marginTop="8dp"android:layout_marginEnd="8dp"android:layout_marginBottom="8dp"app:layout_constraintBottom_toTopOf="@+id/guideline"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.0"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.0"android:background="@drawable/edge"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:id="@+id/et"android:layout_width="match_parent"android:layout_height="wrap_content"android:minLines="8"android:text="123456789"/></LinearLayout></ScrollView>说明: solid为填充⾊即内部的背景填充⾊,stroke 为边框可以设置颜⾊和宽度效果如下:2、设置边框颜⾊案例:在drawable中新建⼀个button_edge.xml⽂件<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="/apk/res/android"><!-- 边框颜⾊值 --><item><shape><solid android:color="#3bbaff"/></shape></item><!--这个是按钮边框设置为四周并且宽度为1--><itemandroid:right="1dp"android:left="1dp"android:top="1dp"android:bottom="1dp"><shape><!--这个是背景颜⾊--><solid android:color="#ffffff"/><!--这个是按钮中的字体与按钮内的四周边距--><padding android:bottom="5dp"android:left="5dp"android:right="5dp"android:top="5dp"/></shape></item></layer-list>使⽤:android:background="@drawable/button_edge"3、设置圆⾓按钮案例:(其实按钮还是⽅形的,只是将外围部分隐藏了⽽已)在drawable中:新建⼀个 button_circle_shape.xml⽂件<?xml version="1.0" encoding="UTF-8"?><shapexmlns:android="/apk/res/android"android:shape="rectangle"><!-- 填充的颜⾊ --><solid android:color="#FFFFFF"/><!-- android:radius 弧形的半径 --><!-- 设置按钮的四个⾓为弧形 --><cornersandroid:radius="5dip"/><!--也可单独设置--><!-- <corners --><!-- android:topLeftRadius="10dp"--><!-- android:topRightRadius="10dp"--><!-- android:bottomRightRadius="10dp"--><!-- android:bottomLeftRadius="10dp"--><!-- /> -->**设置⽂字padding**<!-- padding:Button⾥⾯的⽂字与Button边界的间隔 --><paddingandroid:left="10dp"android:top="10dp"android:right="10dp"android:bottom="10dp"/></shape>使⽤:android:background="@drawable/shape"4、设置圆⾓图⽚案例1 简单的设置:(不能添加⾃定义图⽚只能设置颜⾊和字体)在drawable中创建⼀个image_circle.xml图⽚<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="/apk/res/android"><solid android:color="#FFFFFF"/><corners android:topLeftRadius="10dp"android:topRightRadius="10dp"android:bottomRightRadius="10dp"android:bottomLeftRadius="10dp"/></shape>使⽤:android:background="@drawable/image_circle"5、真实案例:edge.xml<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="/apk/res/android"><!-- 边框颜⾊值 --><item><shape><solid android:color="#3bbaff"/></shape></item><!--这个是按钮边框设置为四周并且宽度为1--><itemandroid:right="1dp"android:left="1dp"android:top="1dp"android:bottom="1dp"><shape><!--这个是背景颜⾊--><solid android:color="#ffffff"/><!--这个是按钮中的字体与按钮内的四周边距--><padding android:bottom="5dp"android:left="5dp"android:right="5dp"android:top="5dp"/></shape></item></layer-list>布局⽂件 LeftFragment.xml:<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="/apk/res/android" xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".LeftFragment"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:layout_gravity="center"android:orientation="vertical"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:orientation="horizontal"android:padding="10dp"><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:src="@mipmap/user"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="⼿⼯登录"android:textSize="20sp"/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:background="@drawable/edge"android:layout_marginLeft="5dp"android:layout_marginRight="5dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:paddingLeft="20dp"android:text="账号"android:textSize="15sp"/><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请输⼊⼯⼚管理系统账号"android:background="@null"android:paddingLeft="10dp"android:textSize="15sp"/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:background="@drawable/edge"android:layout_marginLeft="5dp"android:layout_marginRight="5dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:paddingLeft="20dp"android:textSize="15sp"android:text="密码"/><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请输⼊⼯⼚管理系统登录密码" android:background="@null"android:paddingLeft="10dp"android:textSize="15sp"/></LinearLayout><CheckBoxandroid:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:text="记住密码"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:text="登录"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="登录出现问题?"/></LinearLayout></FrameLayout>。

Android自定义Drawable实现圆角效果

Android自定义Drawable实现圆角效果

Android⾃定义Drawable实现圆⾓效果Drawable是⼀种可绘制资源的载体,如图形、图像等。

在实际开发中可以作为view的背景。

主要有静态和动态两种⽅式,静态通过xml描述使⽤,动态即⾃定义Drawable。

本⽂实现⼀个圆形和圆⾓的背景图⽚效果。

效果图:实现⽅式:1.初始化⼀个BitmapShader着⾊器对象;2.将着⾊器对象set给画笔;3.在画布上绘制圆或圆⾓即可;4.使⽤,view.setBackgroundDrawable或者 ImageView.setImageDrawablepackage com.mydrawable.musk;import android.graphics.Bitmap;import android.graphics.BitmapShader;import android.graphics.Canvas;import android.graphics.ColorFilter;import android.graphics.Paint;import android.graphics.PixelFormat;import android.graphics.Shader;import android.graphics.drawable.Drawable;/*** Created by musk.*/public class CircleDrawable extends Drawable {private Paint mPaint;private int mWidth;private Bitmap mBitmap;public CircleDrawable(Bitmap bitmap) {mBitmap = bitmap;//着⾊器,设置横向和纵向的着⾊模式为平铺BitmapShader bitmapShader = new BitmapShader(mBitmap,Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setDither(true);mPaint.setShader(bitmapShader);mWidth = Math.min(mBitmap.getWidth(), mBitmap.getHeight());}//绘制@Overridepublic void draw(Canvas canvas) {canvas.drawCircle(mWidth / 2, mWidth / 2, mWidth / 2, mPaint);}//设置透明度值@Overridepublic void setAlpha(int alpha) {mPaint.setAlpha(alpha);}//设置颜⾊过滤器@Overridepublic void setColorFilter(ColorFilter colorFilter) {mPaint.setColorFilter(colorFilter);}//返回不透明度@Overridepublic int getOpacity() {return PixelFormat.TRANSLUCENT;}//返回图⽚实际的宽⾼@Overridepublic int getIntrinsicWidth() {return mWidth;}@Overridepublic int getIntrinsicHeight() {return mWidth;}}⾃定义Drawable有五个⽅法必须覆写,draw()、setAlpha()、setColorFilter()、getOpacity(),另外的getIntrinsicWidth()和getIntrinsicHeight()是在view设置wrap_content时设置drawable的宽度和⾼度。

自定义view实现圆角图片(终审稿)

自定义view实现圆角图片(终审稿)
第二个就是获取RoundImageAttrs_RoundType,获取完毕后,记得一定要调用();对资源进行释放。以便后面的其他代码可以访问这些属性资源。(理解的不透彻,但记住释放就ok)
?
到现在为止我们完成了万里长征第一步,获取到了我们自定义控件的属性了。
接下来就是我们的重头戏,重绘图片。下面我们重写了OnDraw函数
那么现在,我们选定了第二种方式,那怎么实现呢有人说我们自己写一个类,直接继承自view,然后所有的绘图和大小的计算我们都自己来搞,这样行吗当然可行,但是我们可能是在重复造轮子,因为我们已经有了一个ImageView,而且它里面给我们做了很多关于图片的操作,我们何不继承自ImageView,然后做少量的工作,就可以实现圆角效果呢。方案确定,好,那我们就开始实现自己的类。
{
(getWidth()/2, getHeight()/2, mBorderRadius, pa);
}
return bit;
}
看看上面的代码,是不是很熟悉,我们之前已经接触过基本的画图方法了。想必,不用解释了,一眼都能看明白。这里我只实现了画圆的,大家可以各自发挥想想,画出各种各样的形状,哈哈,是不是很容易,我们自己实现了圆角图像,同时对于android自定义view的绘制也有了大致了解。
1
(mMashBitmap, 0,0, mPaint); 此时,bitmap中保存的就是叠加之后的图片了,也就是我们最终需要的圆角图片了。最后我们将这个bitmap绘制到OnDraw函数给我们传递进来的<br>canvas上,所有工作就基本做完了。(bitmap, 0,0, null);<br>最后将绘制好的图片保存起来。<em id="__mceDel">mWeakBitmap = new WeakReference<Bitmap>(bitmap);<br><br></em>下一次执行ondraw 的时候,我们就直接用保存好的bitmap进行绘制了,也就是我们代码中else的部分。<br><br>最艰难的部分说完了,哈哈,如果不理解还是得多看几遍。接下来的工作就轻松了很多,对了,我们还没有实现之前那个绘制形状的函数呢。我们来绘制把。很容易的。<br><br>

Android自定义ViewGroup实现带箭头的圆角矩形菜单

Android自定义ViewGroup实现带箭头的圆角矩形菜单

Android⾃定义ViewGroup实现带箭头的圆⾓矩形菜单本⽂和⼤家⼀起做⼀个带箭头的圆⾓矩形菜单,⼤概长下⾯这个样⼦:要求顶上的箭头要对准菜单锚点,菜单项按压反⾊,菜单背景⾊和按压⾊可配置。

最简单的做法就是让UX给个三⾓形的图⽚往上⼀贴,但是转念⼀想这样是不是太low了点,⽽且不同分辨率也不太好适配,⼲脆⾃定义⼀个ViewGroup吧!⾃定义ViewGroup其实很简单,基本都是按⼀定的套路来的。

⼀、定义⼀个attrs.xml就是声明⼀下你的这个⾃定义View有哪些可配置的属性,将来使⽤的时候可以⾃由配置。

这⾥声明了7个属性,分别是:箭头宽度、箭头⾼度、箭头⽔平偏移、圆⾓半径、菜单背景⾊、阴影⾊、阴影厚度。

<resources><declare-styleable name="ArrowRectangleView"><attr name="arrow_width" format="dimension" /><attr name="arrow_height" format="dimension" /><attr name="arrow_offset" format="dimension" /><attr name="radius" format="dimension" /><attr name="background_color" format="color" /><attr name="shadow_color" format="color" /><attr name="shadow_thickness" format="dimension" /></declare-styleable></resources>⼆、写⼀个继承ViewGroup的类,在构造函数中初始化这些属性这⾥需要⽤到⼀个obtainStyledAttributes()⽅法,获取⼀个TypedArray对象,然后就可以根据类型获取相应的属性值了。

glide设置圆角方法

glide设置圆角方法

glide设置圆角方法(原创实用版3篇)目录(篇1)1.Glide 简介2.设置圆角的方法3.示例代码正文(篇1)1.Glide 简介Glide 是一个流行的 Android 图像加载库,它提供了高效的图片加载和缓存功能。

Glide 旨在简化图片加载的过程,并提供更好的性能和用户体验。

在 Glide 中,我们可以通过设置圆角来改变图片的显示效果,使图片更加圆润。

2.设置圆角的方法要在 Glide 中设置圆角,我们可以使用`setCircleClip()`方法。

这个方法接受一个布尔值,当为`true`时,图片将显示为圆形,当为`false`时,图片将显示为矩形。

此外,我们还可以通过`setRadius()`方法设置圆角的半径。

3.示例代码下面是一个使用 Glide 设置圆角的示例代码:```javaimport com.bumptech.glide.Glide;import com.bumptech.glide.load.ImageResource;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);setContentView(yout.activity_main);// 加载图片并设置圆角Glide.with(this).load(R.drawable.image).circleClip(true) // 设置图片为圆形.radius(50) // 设置圆角半径.into(imageView);}}```在这个示例中,我们使用`Glide.with()`方法加载`R.drawable.image`中的图片,并使用`circleClip(true)`方法设置图片为圆形,同时使用`radius(50)`方法设置圆角半径。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

android 自定义圆角头像以及使用declare-styleable进行配置属性解析由于最新项目中正在检查UI是否与效果图匹配,结果关于联系人模块给的默认图片是四角稍带弧度的圆角,而我们截取的图片是正方形的,现在要给应用统一替换。

应用中既用到大圆角头像(即整个头像是圆的)又用到四角稍带弧度的圆角头像,封装一下以便重用。

以下直接见代码[java] view plain copy 在CODE上查看代码片派生到我的代码片package com.test.demo;import com.test.demo.R;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapShader;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.RectF;import android.graphics.Shader.TileMode;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.os.Bundle;import android.os.Parcelable;import android.util.AttributeSet;import android.util.Log;import android.util.TypedValue;import android.widget.ImageView;/*** 圆角imageview*/public class RoundImageView extends ImageView {private static final String TAG = "RoundImageView";/*** 图片的类型,圆形or圆角*/private int type;public static final int TYPE_CIRCLE = 0;public static final int TYPE_ROUND = 1;/*** 圆角大小的默认值*/private static final int CORNER_RADIUS_DEFAULT = 10;/*** 圆角的大小*/private int mCornerRadius;/*** 绘图的Paint*/private Paint mBitmapPaint;// 按下状态颜色private Paint mPressedColorPaint;private int pressedColor;/*** 圆角的半径*/private int mRadius;/*** 3x3 矩阵,主要用于缩小放大*/private Matrix mMatrix;/*** view的宽度*/private int mWidth;private RectF mRoundRect;public RoundImageView(Context context, AttributeSet attrs) {super(context, attrs);mMatrix = new Matrix();mBitmapPaint = new Paint();mBitmapPaint.setAntiAlias(true);TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.RoundImageView);pressedColor = a.getColor(R.styleable.RoundImageView_pressed_color, -1);if (pressedColor != -1) {mPressedColorPaint = new Paint();mPressedColorPaint.setAntiAlias(true);mPressedColorPaint.setColor(pressedColor);}mCornerRadius = a.getDimensionPixelSize(R.styleable.RoundImageView_corner_radius, (int) TypedValue.applyDimension(PLEX_UNIT_DIP,CORNER_RADIUS_DEFAULT, getResources().getDisplayMetrics()));// 默认为10dp type = a.getInt(R.styleable.RoundImageView_type, TYPE_CIRCLE);// 默认为Circlea.recycle();}public RoundImageView(Context context) {this(context, null);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec);/*** 如果类型是圆形,则强制改变view的宽高一致,以小值为准*/if (type == TYPE_CIRCLE) {mWidth = Math.min(MeasureSpec.getSize(widthMeasureSpec),MeasureSpec.getSize(heightMeasureSpec));mRadius = mWidth / 2;}}/*** 初始化BitmapShader*/private void setUpShader() {Drawable drawable = getDrawable();if (drawable == null) {return;}Bitmap bmp = drawableToBitamp(drawable);// 将bmp作为着色器,就是在指定区域内绘制bmp// 渲染图像,使用图像为绘制图形着色BitmapShader mBitmapShader = new BitmapShader(bmp, TileMode.CLAMP,TileMode.CLAMP);float scale = 1.0f;if (type == TYPE_CIRCLE) {// 拿到bitmap宽或高的小值int bSize = Math.min(bmp.getWidth(), bmp.getHeight());scale = mWidth * 1.0f / bSize;} else if (type == TYPE_ROUND) {if (!(bmp.getWidth() == getWidth() && bmp.getHeight() == getHeight())) {// 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值;scale = Math.max(getWidth() * 1.0f / bmp.getWidth(),getHeight() * 1.0f / bmp.getHeight());}}// shader的变换矩阵,我们这里主要用于放大或者缩小mMatrix.setScale(scale, scale);// 设置变换矩阵mBitmapShader.setLocalMatrix(mMatrix);// 设置shadermBitmapPaint.setShader(mBitmapShader);}@Overrideprotected void onDraw(Canvas canvas) {if (getDrawable() == null) {return;}setUpShader();if (type == TYPE_ROUND) {canvas.drawRoundRect(mRoundRect, mCornerRadius, mCornerRadius,mBitmapPaint);if (isPressed() && mPressedColorPaint != null) {canvas.drawRoundRect(mRoundRect, mCornerRadius, mCornerRadius,mPressedColorPaint);}} else {canvas.drawCircle(mRadius, mRadius, mRadius, mBitmapPaint);if (isPressed() && mPressedColorPaint != null) {canvas.drawCircle(mRadius, mRadius, mRadius, mPressedColorPaint);}}}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);Log.d(TAG, "onSizeChanged,w=" + w + ",h=" + h + ",oldw=" + oldw+ ",oldh=" + oldh);// 圆角图片的范围if (type == TYPE_ROUND) {mRoundRect = new RectF(0, 0, w, h);}}/*** drawable转bitmap*/private Bitmap drawableToBitamp(Drawable drawable) {if (drawable instanceof BitmapDrawable) {BitmapDrawable bd = (BitmapDrawable) drawable;return bd.getBitmap();}int w = drawable.getIntrinsicWidth();int h = drawable.getIntrinsicHeight();Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);drawable.setBounds(0, 0, w, h);drawable.draw(canvas);return bitmap;}private static final String STATE_INSTANCE = "state_instance";private static final String STATE_TYPE = "state_type";private static final String STATE_BORDER_RADIUS = "state_border_radius"; private static final String STATE_PRESSED_COLOR = "state_pressed_color";@Overrideprotected Parcelable onSaveInstanceState() {Bundle bundle = new Bundle();bundle.putParcelable(STA TE_INSTANCE, super.onSaveInstanceState());bundle.putInt(STA TE_TYPE, type);bundle.putInt(STA TE_BORDER_RADIUS, mCornerRadius);bundle.putInt(STA TE_PRESSED_COLOR, pressedColor);return bundle;}@Overrideprotected void onRestoreInstanceState(Parcelable state) {if (state instanceof Bundle) {Bundle bundle = (Bundle) state;super.onRestoreInstanceState(((Bundle) state).getParcelable(STATE_INSTANCE));this.type = bundle.getInt(STATE_TYPE);this.mCornerRadius = bundle.getInt(STA TE_BORDER_RADIUS);this.pressedColor = bundle.getInt(STA TE_PRESSED_COLOR);if (pressedColor != -1) {mPressedColorPaint = new Paint();mPressedColorPaint.setAntiAlias(true);mPressedColorPaint.setColor(pressedColor);}} else {super.onRestoreInstanceState(state);}}public void setType(int type) {if (this.type != type) {this.type = type;if (this.type != TYPE_ROUND && this.type != TYPE_CIRCLE) {this.type = TYPE_CIRCLE;}requestLayout();}}@Overrideprotected void dispatchSetPressed(boolean pressed) {// imageView.setClickable(true),或imageView.setOnClickListener时才可触发dispatchSetPressedsuper.dispatchSetPressed(pressed);invalidate();}}declare-styleable:declare-styleable是给自定义控件添加自定义属性用的。

相关文档
最新文档