Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 自定義圓形ImageView 實現思路 -- Android 學習之路

自定義圓形ImageView 實現思路 -- Android 學習之路

編輯:關於Android編程

自定義圓形ImageView

圓形ImageView在頭像顯示用的比較普遍了,今天對於實現圓形ImageView做個總結;

主要思路是 重寫 onDraw() ;方法有兩個:

使用paint的Shader(著色器)將圖片印在一個圓的畫板上 使用Bitmap創建一個空的Canvas(畫板),在畫板上畫一個圓和顯示的圖片,paint圖像混合模式顯示

著色器 方式

不帶邊框

具體思路

將圖片壓縮到和控件的大小一致 創建Bitmap 著色器 創建畫筆並設置著色器 使用帶有著色器的畫筆在畫板上畫圓
    private void drawShader(Canvas canvas) {
        Drawable mDrawable = getDrawable();
        if (mDrawable == null) return;
        if (mDrawable instanceof BitmapDrawable){
            Bitmap bmp = ((BitmapDrawable)mDrawable).getBitmap();
            if (bmp == null) return;
            //圖片縮放,參數2 目標寬度,參數3目標高度,參數4 是否過濾
            bmp = Bitmap.createScaledBitmap(bmp,getWidth(),getHeight(),true);
            //著色器
            Shader shader = new BitmapShader(bmp, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            paint = new Paint();
            paint.setShader(shader);
            canvas.drawCircle(getWidth()/2,getWidth()/2,getWidth()/2,paint);
        }
    }

效果

無邊框效果

加邊框

有時候我們需要為頭像加上一個圓的邊框顯得更好看一點,其實這個也很好實現,在繪制圖片之前先繪制一個帶有顏色的圓,根據邊框的大小,將圖片縮小一點,這樣就將邊框顯示出來了。

畫邊框

paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(outColor);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/2,paint);

繪制圖片 將邊框大小空出來 (getWidth()-outWidth*2)/2

    private void drawShader(Canvas canvas) {
        Drawable mDrawable = getDrawable();
        if (mDrawable == null) return;
        if (mDrawable instanceof BitmapDrawable){
            Bitmap bmp = ((BitmapDrawable)mDrawable).getBitmap();
            if (bmp == null) return;
            //圖片縮放,參數2 目標寬度,參數3目標高度,參數4 是否過濾
            bmp = Bitmap.createScaledBitmap(bmp,getWidth(),getHeight(),true);
            //著色器
            Shader shader = new BitmapShader(bmp, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            paint = new Paint();
            paint.setShader(shader);
            canvas.drawCircle(getWidth()/2,getWidth()/2,(getWidth()-outWidth*2)/2,paint);
        }
    }

效果

邊框效果

著色器方式全部代碼

自定義屬性 邊框顏色和寬度



    
        
        
    

重寫 onDraw() 繪制圖片

package com.skymxc.lesson_36_view_override;

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.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;

/**
 * Created by sky-mxc
 */
public class CircleImageView extends ImageView {
    private static final String TAG = "CircleImageView";

    private int outWidth = 2;
    private int outColor = Color.RED;

    private Paint paint;

    public CircleImageView(Context context) {
        this(context,null,0);
    }

    public CircleImageView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
//        canvas.drawColor(Color.YELLOW);
        paint.setColor(outColor);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/2,paint);
        drawShader(canvas);

    }


    private void drawShader(Canvas canvas) {
        Drawable mDrawable = getDrawable();
        if (mDrawable == null) return;
        if (mDrawable instanceof BitmapDrawable){
            Bitmap bmp = ((BitmapDrawable)mDrawable).getBitmap();
            if (bmp == null) return;
            //圖片縮放,參數2 目標寬度,參數3目標高度,參數4 是否過濾
            bmp = Bitmap.createScaledBitmap(bmp,getWidth(),getHeight(),true);
            //著色器
            Shader shader = new BitmapShader(bmp, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            paint = new Paint();
            paint.setShader(shader);
            canvas.drawCircle(getWidth()/2,getWidth()/2,(getWidth()-outWidth*2)/2,paint);
        }
    }

    public void initAttrs(AttributeSet attrs){
        TypedArray array = getContext().obtainStyledAttributes(attrs,R.styleable.CircleImageView);
        int len =  array.length();
        for(int i=0;i<len;i++){ attr="array.getIndex(i);" case="" initattrs:="" int="" outwidth="" +this.outwidth);"="" pre="" r.styleable.circleimageview_out_color:="" r.styleable.circleimageview_out_width:="" switch="" this.outcolor="array.getColor(attr,Color.GREEN);" this.outwidth="(int)">

 使用圖片混合模式顯示

創建 Bitmap 使用圖片混合模式 將圖片和圓形交叉顯示

  private Bitmap getCircleBitmap(){
        Drawable mDrawable = getDrawable();
        if (mDrawable == null) return null;
        if (mDrawable instanceof BitmapDrawable){
            Bitmap bmp = ((BitmapDrawable)mDrawable).getBitmap();
            if (bmp == null) return null;
            paint  = new Paint();
            paint.setAntiAlias(true);
            //創建空的位圖
            Bitmap output = Bitmap.createBitmap(getWidth(),getHeight(), Bitmap.Config.ARGB_8888);
            //創建畫板,以位圖進行創建
            Canvas canvas= new Canvas(output);
            //Bitmap就成了 透明的圖片
            canvas.drawColor(Color.TRANSPARENT);

            //畫一個圓形 和圖像大小一致
            paint.setColor(Color.WHITE);
            canvas.drawCircle(output.getWidth()/2,output.getHeight()/2,output.getWidth()/2,paint);

//            //paint 相交模式 必須在 兩者中間定義  顯示交叉的地方  ;前面是 dst;後面是 src
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
//
//            //繪制 Bitmap
            Rect src = new Rect(0,0,bmp.getWidth(),bmp.getHeight());
            RectF dst = new RectF(0,0,output.getWidth(),output.getHeight());
            canvas.drawBitmap(bmp,src,dst,paint);
            return  output;


        }

        return  null;
    }

@Override
protected void onDraw(Canvas canvas) {
      Bitmap bmp=  getCircleBitmap();
       canvas.drawBitmap(bmp,0,0,paint);

}

對於這種方式的實現主要在於 paint 的交叉模式; PorterDuffXfermode

實現的方式有很多種 目前想到兩種. 未完待續。。。。。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved