(转)Android开源系列:CircleImageView自定义圆形控件的使用

    xiaoxiao2021-03-25  119

    原地址:http://blog.csdn.net/nupt123456789/article/details/24886451?utm_source=tuicool&utm_medium=referral

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

    主要的类:

    [java]  view plain  copy   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;           }       }          @Override       public ScaleType getScaleType() {           return SCALE_TYPE;       }          @Override       public void setScaleType(ScaleType scaleType) {           if (scaleType != SCALE_TYPE) {               throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));           }       }          @Override       protected void onDraw(Canvas canvas) {           if (getDrawable() == null) {               return;           }              canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);           canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);       }          @Override       protected 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();       }          @Override       public void setImageBitmap(Bitmap bm) {           super.setImageBitmap(bm);           mBitmap = bm;           setup();       }          @Override       public void setImageDrawable(Drawable drawable) {           super.setImageDrawable(drawable);           mBitmap = getBitmapFromDrawable(drawable);           setup();       }          @Override       public 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(00, 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(00, 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

    [html]  view plain  copy   <?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>   使用时的布局文件:

    [html]  view plain  copy   <?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" >       <RelativeLayout           android:layout_width="match_parent"           android:layout_height="0dp"           android:layout_weight="1"           android:padding="@dimen/base_padding"           android:background="@color/light">              <de.hdodenhof.circleimageview.CircleImageView               android: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>          <RelativeLayout           android:layout_width="match_parent"           android:layout_height="0dp"           android:layout_weight="1"           android:padding="@dimen/base_padding"           android:background="@color/dark">              <de.hdodenhof.circleimageview.CircleImageView               android: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是自定义控件,也即是:无论你设置的图片是什么样的,显示出来的就是圆的。比如:易信中用户头像的设置,无论用户拍什么的照片,显示出来都是一个圆的。

    拓展阅读:

    还有一个更加强大的RoundedImageView,还支持圆角,椭圆等等。

    https://github.com/vinc3m1/RoundedImageView

    转载请注明原文地址: https://ju.6miu.com/read-6218.html

    最新回复(0)