1. 程式人生 > >android 圓形ImageView CircleImageView

android 圓形ImageView CircleImageView

原文
package com.example.administrator.spchain;


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.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;

public class CircleImageView extends AppCompatImageView {

    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);//繫結渲染器需要渲染的圖片,mbitmap

        mBitmapPaint.setAntiAlias(true);//用於畫圖片的畫筆設定抗鋸齒
        mBitmapPaint.setShader(mBitmapShader);//繫結畫筆的渲染器

        mBorderPaint.setStyle(Paint.Style.STROKE);//設定畫邊界的畫筆
        mBorderPaint.setAntiAlias(true);
        mBorderPaint.setColor(mBorderColor);
        mBorderPaint.setStrokeWidth(mBorderWidth);

        mBitmapHeight = mBitmap.getHeight();//獲得mbitmap的高度
        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() / mBitmapHeight;
            dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
        } else {
            scale = mDrawableRect.width() / 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);
    }

}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:gcs="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.administrator.spchain.CircleImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/avatar"
        android:src="@mipmap/ic_launcher"
        gcs:border_width="0dp"
        />







</LinearLayout>
<resources>

    <!-- 圓形頭像 -->
    <declare-styleable name="CircleImageView">
        <attr name="border_width" format="dimension" />
        <attr name="border_color" format="color" />
    </declare-styleable>

</resources>

相關推薦

android 圓形ImageView CircleImageView

原文 package com.example.administrator.spchain; import android.content.Context; import android.content.res.TypedArray; import android.gr

Android圓形圖片CircleImageView的使用和分析

在專案開發中,我們經常需要用到圓形圖片效果,典型案例是使用者頭像的顯示。如圖所示。下面我們使用開源控制元件CircleImageView來實現該效果。CircleImageView專案下載地址:https://github.com/hdodenhof/CircleImage

Android學習筆記-繪制圓形ImageView實例

eight font private cte class get wid actor oid 現在很多的APP都很喜歡圓形的頭像,這裏就簡單的寫個圓形的ImageView~ 第三方圓形ImageView控件: RoundedImageView CircleImageView

Android】自己定義圓形ImageView(圓形頭像 可指定大小)

代碼實現 err float avi rim war tor pos dsm 近期在仿手Q的UI,這裏面常常要用到的就是圓形頭像,看到 在android中畫圓形圖片的幾種辦法 這篇文章,了解了制作這樣的頭像的原理.只是裏面提供的方法另一個不足的地方就是

Android開發圓形ImageView實現

radi appcompat con code roi contex draw ttr extends 1、自定義屬性,在value文件夾下新建attrs文件,聲明如下屬性 <declare-styleable name="CircleImageView">

Android 三種方式實現圓形ImageView

所有方式均繼承了ImageView 圓形圖片實現一:BitmapShader package com.open.widget; import android.content.Context; import android.graphics.Bitmap; impor

Android實現圓形Imageview,帶白色邊框

最近做了個圓形Imageview,外面有白色邊框 有需要的同學可以看看,效果如下 附上實現程式碼 RoundImageView: public class RoundImageView

Android圓形圖片控制元件CircleImageView的使用

自定義CircleImageView繼承ImageView package com.zhoujian.circleimageview.view; import android.content.Context; import android.conten

Android簡單模糊背景和圓形ImageView

  //載入頭像和模糊背景        Glide.with(getActivity()).load(你的圖片地址)                .bitmapTransform(new BlurTransformation(getActivity(),10),new C

android自定義view-打造圓形ImageView(一)

package com.beyole.view; import com.beyole.roundimageview.R; import android.content.Context; import android.content.res.TypedArray; import android.graphi

Android模仿QQ音樂播放旋轉的圓形ImageView

這裡會用到背景虛化和圓形的ImageView控制元件,可以參考我之前的博文。 背景虛化 首先繼承AnimatorUpdateListener類,對控制元件狀態進行更新,程式碼如下: class MyAnimatorUpdateListener implements A

Android中快速自定義圓形ImageView圖形!

1 public class ImageViewPlus extends ImageView{ 2 /** 3 * android.widget.ImageView 4 */ 5 public static final int TYPE_NONE =

Android 圓角、圓形 ImageView 實現

一、 特點基於AppCompatImageView擴充套件支援圓角、圓形顯示可繪製邊框,圓形時可繪製內外兩層邊框支援邊框不覆蓋圖片可繪製遮罩......二、基本原理我們要實現的圖片控制元件繼承自AppCompatImageView,它是ImageView的子類,但提供了更好的相容性,我們在此基礎上添加了若干自

android自定義view-打造圓形ImageView(四)終結篇

package com.beyole.view; import java.lang.ref.WeakReference; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitm

android圓形ImageView

2014.3.25修改,請參看這個開源專案:https://github.com/hdodenhof/CircleImageView 參考了網上一些人的程式碼,自己做了一些修改 package com.example.testsam; import android.c

android自定義view-打造圓形ImageView(二)

package com.beyole.view; import java.lang.ref.WeakReference; import android.content.Context; import android.content.res.TypedArray; import android.graphi

Android 圓角圓形ImageView(超簡單實現)

前言:今天偶然看到我之前寫過的一篇部落格 Android專案中遇到的坑之(Android圓角圓形圖 一),我在想,這不就是在模仿ImageView麼,我為什麼要模仿,直接拿來用不是更好麼?我能直接在ImageView的原始碼上去改改程式碼? 於是就有了下面這篇文

Androidimageview中獲得bitmap的方法

blog bit win matrix image logs led bitmap raw 第一種: 使用setDrawingCacheEnabled()和getDrawingCache()這兩種方法,第一個是為了設置是否開啟緩存,第二個就可以直接獲得imageview中

自定義圓形ImageView(解決Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();報錯問題)

eight err cts 使用 stat surf 否則 自定義image fin package com.bottle.bottlelilibrary.view; import android.content.Context; import android.grap

Android開發 - ImageView加載Base64編碼的圖片

base64編碼 [] 地址 加載本地 .cn ... ear 情況 ring 在我們開發應用的過程中,並不是所有情況下都請求圖片的URL或者加載本地圖片,有時我們需要加載Base64編碼的圖片。這種情況出現在服務端需要動態生成的圖片,比如: 二維碼 圖形驗證碼 ...