1.自定义圆形控件github地址: https://github.com/hdodenhof/CircleImageView

主要的类:

package de.hdodenhof.circleimageview;import edu.njupt.zhb.main.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.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.RectF;import android.graphics.Shader;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.ColorDrawable;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.widget.ImageView;public class CircleImageView extends ImageView {private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;private static final int COLORDRAWABLE_DIMENSION = 1;private static final int DEFAULT_BORDER_WIDTH = 0;private static final int DEFAULT_BORDER_COLOR = Color.BLACK;private final RectF mDrawableRect = new RectF();private final RectF mBorderRect = new RectF();private final Matrix mShaderMatrix = new Matrix();private final Paint mBitmapPaint = new Paint();private final Paint mBorderPaint = new Paint();private int mBorderColor = DEFAULT_BORDER_COLOR;private int mBorderWidth = DEFAULT_BORDER_WIDTH;private Bitmap mBitmap;private BitmapShader mBitmapShader;private int mBitmapWidth;private int mBitmapHeight;private float mDrawableRadius;private float mBorderRadius;private boolean mReady;private boolean mSetupPending;public CircleImageView(Context context) {super(context);}public CircleImageView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public CircleImageView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);super.setScaleType(SCALE_TYPE);TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);a.recycle();mReady = true;if (mSetupPending) {setup();mSetupPending = false;}}@Overridepublic ScaleType getScaleType() {return SCALE_TYPE;}@Overridepublic void setScaleType(ScaleType scaleType) {if (scaleType != SCALE_TYPE) {throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));}}@Overrideprotected void onDraw(Canvas canvas) {if (getDrawable() == null) {return;}canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);setup();}public int getBorderColor() {return mBorderColor;}public void setBorderColor(int borderColor) {if (borderColor == mBorderColor) {return;}mBorderColor = borderColor;mBorderPaint.setColor(mBorderColor);invalidate();}public int getBorderWidth() {return mBorderWidth;}public void setBorderWidth(int borderWidth) {if (borderWidth == mBorderWidth) {return;}mBorderWidth = borderWidth;setup();}@Overridepublic void setImageBitmap(Bitmap bm) {super.setImageBitmap(bm);mBitmap = bm;setup();}@Overridepublic void setImageDrawable(Drawable drawable) {super.setImageDrawable(drawable);mBitmap = getBitmapFromDrawable(drawable);setup();}@Overridepublic void setImageResource(int resId) {super.setImageResource(resId);mBitmap = getBitmapFromDrawable(getDrawable());setup();}private Bitmap getBitmapFromDrawable(Drawable drawable) {if (drawable == null) {return null;}if (drawable instanceof BitmapDrawable) {return ((BitmapDrawable) drawable).getBitmap();}try {Bitmap bitmap;if (drawable instanceof ColorDrawable) {bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);} else {bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);}Canvas canvas = new Canvas(bitmap);drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());drawable.draw(canvas);return bitmap;} catch (OutOfMemoryError e) {return null;}}private void setup() {if (!mReady) {mSetupPending = true;return;}if (mBitmap == null) {return;}mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);mBitmapPaint.setAntiAlias(true);mBitmapPaint.setShader(mBitmapShader);mBorderPaint.setStyle(Paint.Style.STROKE);mBorderPaint.setAntiAlias(true);mBorderPaint.setColor(mBorderColor);mBorderPaint.setStrokeWidth(mBorderWidth);mBitmapHeight = mBitmap.getHeight();mBitmapWidth = mBitmap.getWidth();mBorderRect.set(0, 0, getWidth(), getHeight());mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2);mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() - mBorderWidth);mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);updateShaderMatrix();invalidate();}private void updateShaderMatrix() {float scale;float dx = 0;float dy = 0;mShaderMatrix.set(null);if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {scale = mDrawableRect.height() / (float) mBitmapHeight;dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;} else {scale = mDrawableRect.width() / (float) mBitmapWidth;dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;}mShaderMatrix.setScale(scale, scale);mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth, (int) (dy + 0.5f) + mBorderWidth);mBitmapShader.setLocalMatrix(mShaderMatrix);}}
自定义的属性:res/values/attrs.xml
<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="CircleImageView">        <attr name="border_width" format="dimension" />        <attr name="border_color" format="color" />    declare-styleable>resources>
使用时的布局文件:
<?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"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:padding="@dimen/base_padding"android:background="@color/light"><de.hdodenhof.circleimageview.CircleImageViewandroid:layout_width="160dp"android:layout_height="160dp"android:layout_centerInParent="true"android:src="@drawable/demo"app:border_width="2dp"app:border_color="@color/dark" />RelativeLayout><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:padding="@dimen/base_padding"android:background="@color/dark"><de.hdodenhof.circleimageview.CircleImageViewandroid:layout_width="160dp"android:layout_height="160dp"android:layout_centerInParent="true"android:src="@drawable/lena"app:border_width="2dp"app:border_color="@color/light" />RelativeLayout>LinearLayout>
效果:

 

Demo下载:http://download.csdn.net/detail/nuptboyzhb/7284553

注意:有些开发者可能也发现了,如果我们需要一个圆形的ImageButton的话,其实,我们没有必要自己写。如果ImageButton的图标是固定不变的,我们完全可以让设计师给我设计一个圆形的图片,然后直接设置再ImageButton上就可以了。但是,请注意,我们这里的圆形ImageView是自定义控件,也即是:无论你设置的图片是什么样的,显示出来的就是圆的。比如:易信中用户头像的设置,无论用户拍什么的照片,显示出来都是一个圆的。

更多相关文章

  1. android 调用系统通讯录添加联系人,并将号码传值到相应的控件内
  2. Android之获取控件的坐标
  3. 控件:ExpandableListView --- 树型组件
  4. 【Android】手机地图功能——利用手机GPS获取用户地理坐标
  5. Android拖动控件改变其位置
  6. android 遍历所有控件
  7. Android学习--动态向SPinner控件中添加数据

随机推荐

  1. 对数vs线性vs二次vs指数形式,到底选择哪种
  2. 机器学习方法出现在AER, JPE, QJE等顶刊
  3. 万字长文述"家庭经济学"进展, 诺奖得主贝
  4. 过去三十年, RCT, DID, RDD, LE, ML, DSG
  5. 空间双重差分法(spatial DID)最新实证pap
  6. 忽略交互效应后果很严重,审稿人很生气!
  7. 妇女能顶半边天, 关于“中国女性”最新研
  8. grid实现12列栅格布局的组件并且实例圣杯
  9. unity常用方法库 持续跟新
  10. 【无偿分享】史上最全Python学习大礼包