所谓自定义控件(或称组件)也就是编写自己的控件类型,而非Android中提供的标准的控件,如TextView,等等.不过自定义的控件一般也都是从标准控件继承来的,或者是多种控件组合,或者是对标准控件的属性进行改变而得到的自己满意的控件.
自定义控件可能会有很多种方法,这里只介绍圆形图片的控件
获取圆形图片工具类(识别各种尺寸图片,自带图片裁剪功能,选取图片的最大正方形画圆)
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.content.Context;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.NinePatchDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* yang
*
* 设置颜色在xml布局文件中由自定义属性配置参数指定
*/
publicclassRoundImageView extends ImageView {
//控件默认长、宽
privateint defaultWidth = 0;
privateint defaultHeight = 0;
public RoundImageView(Context context){
super(context);
}
public RoundImageView(Context context,AttributeSet attrs) {
super(context, attrs);
}
public RoundImageView(Context context,AttributeSet attrs,int defStyle) {
super(context, attrs, defStyle);
}
@Override
protectedvoid onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable ==null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
this.measure(0, 0);
if (drawable.getClass() == NinePatchDrawable.class)
return;
Bitmap b = ((BitmapDrawable)drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888,true);
if (defaultWidth == 0) {
defaultWidth = getWidth();
}
if (defaultHeight == 0) {
defaultHeight = getHeight();
}
// 保证重新读取图片后不会因为图片大小而改变控件宽、高的大小(针对宽、高为wrap_content布局的imageview,但会导致margin无效)
int radius = 0;
radius = (defaultWidth <defaultHeight ? defaultWidth
: defaultHeight) / 2;
Bitmap roundBitmap =getCroppedRoundBitmap(bitmap, radius);
canvas.drawBitmap(roundBitmap,defaultWidth / 2 - radius, defaultHeight
/ 2 - radius, null);
}
/**
*获取裁剪后的圆形图片
*
*@param radius
* 半径
*/
public Bitmap getCroppedRoundBitmap(Bitmapbmp,intradius) {
Bitmap scaledSrcBmp;
int diameter = radius * 2;
// 为了防止宽高不相等,造成圆形图片变形,因此截取长方形中处于中间位置最大的正方形图片
int bmpWidth = bmp.getWidth();
int bmpHeight = bmp.getHeight();
int squareWidth = 0, squareHeight = 0;
int x = 0, y = 0;
Bitmap squareBitmap;
if (bmpHeight > bmpWidth) {//高大于宽
squareWidth = squareHeight =bmpWidth;
x = 0;
y = (bmpHeight - bmpWidth) /2;
// 截取正方形图片
squareBitmap = Bitmap.createBitmap(bmp,x, y, squareWidth,
squareHeight);
} elseif (bmpHeight < bmpWidth) {//宽大于高
squareWidth = squareHeight =bmpHeight;
x = (bmpWidth - bmpHeight) /2;
y = 0;
squareBitmap = Bitmap.createBitmap(bmp,x, y, squareWidth,
squareHeight);
} else {
squareBitmap = bmp;
}
if (squareBitmap.getWidth() != diameter
|| squareBitmap.getHeight() !=diameter) {
scaledSrcBmp = Bitmap.createScaledBitmap(squareBitmap,diameter,
diameter, true);
} else {
scaledSrcBmp = squareBitmap;
}
/*
*获取圆形图片
*/
Bitmap output = Bitmap.createBitmap(scaledSrcBmp.getWidth(),
scaledSrcBmp.getHeight(),Config.ARGB_8888);
Canvas canvas = new Canvas(output);
Paint paint = new Paint();
Rect rect = new Rect(0, 0, scaledSrcBmp.getWidth(),
scaledSrcBmp.getHeight());
paint.setAntiAlias(true); //抗锯齿标志,减轻锯齿情况
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);//透明色
/*drawCircle四个参数
* cx:圆心的x坐标。
cy:圆心的y坐标。
radius:圆的半径。
paint:绘制时所使用的画笔。
*/
canvas.drawCircle(scaledSrcBmp.getWidth() / 2,
scaledSrcBmp.getHeight() / 2,scaledSrcBmp.getWidth()/ 2,
paint);
/*
* SRC_IN为原图,scaledSrcBmp为目标图,把代码中的SRC_IN换成下图指定的模式就会出现对应的效果图。
*/
paint.setXfermode(newPorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(scaledSrcBmp, rect,rect, paint);
return output;
}
}
调用(只需要将控件名改为包名+自定义控件类名此控件的使用和Imageview一样)
<com.hpu.RoundImage.RoundImageView
android:id="@+id/imageloder"
android:layout_width="200dp"
android:layout_height="200dp"
android:src="@drawable/ic_launcher"/>