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>

  • 相关阅读:
    EXTJS 4.2 资料 控件之checkboxgroup的用法(静态数据)
    EXTJS 4.2 资料 控件之Window窗体相关属性的用法
    EXTJS 4.2 资料 控件之textfield文本框加事件的用法
    Entity Framework 学习笔记(一)之数据模型 数据库
    EXTJS 4.2 资料 控件之checkboxgroup的用法(动态数据)
    EXTJS 4.2 资料 控件之Grid 列鼠标悬停提示
    Entity Framework 学习笔记(二)之数据模型 Model 使用过程
    EXTJS 4.2 资料 控件之radiogroup 的用法
    EXTJS API
    vue移动端弹框组件,vue-layer-mobile
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/4685852.html
Copyright © 2011-2022 走看看