zoukankan      html  css  js  c++  java
  • CircleImageView自定义圆形控件的使用

    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;
        }
      }
    
      @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(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" >
      <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>

  • 相关阅读:
    SnagIt 9-12 注册码
    【工具推荐】LICEcap –GIF 屏幕录制工具
    linux笔记一(基础命令)
    C#性能优化:延迟初始化Lazy<T>
    CSS3实现漂亮ToolTips
    mysql数据库sql优化
    精简代码,为网站减负的十大建议
    10个简单步骤,完全理解SQL
    13个mysql数据库的实用SQL小技巧
    MyBatis源码解读(二)
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/4685852.html
Copyright © 2011-2022 走看看