ImageLoader displayers 之CircleBitmapDisplayer

ImageLoader这个图片加载器是我经常使用额一个图片加载器(https://github.com/nostra13/Android-Universal-Image-Loader

这个图片加载器在加载的时候是支持图片加载效果的,原本自带了RoundBitmapDisplayer,圆角图片显示器。

但是项目的需要,我要弄一个圆形的图片,这样有两个思路,

其一,是弄一个CircleImageView 直接改写ImageView 以达到圆形图片的效果

但是这样有个问题,就是在列表加载的时候,这个图片是不能缓存的,每次都是用重新切图

其二,使用ImageLoader的BitmapDisplayer ,这个出来的图片是可以缓存到内存中的,所以在列表中加载比较有优势

 

下面就是实现这种功能代码

首先我们要实现一个最重要的CircleDrawable,就是靠这个实现了圆形的功能

 
package auggie.library.displayers;



import android.graphics.Bitmap;

import android.graphics.BitmapShader;

import android.graphics.Canvas;

import android.graphics.ColorFilter;

import android.graphics.Matrix;

import android.graphics.Paint;

import android.graphics.PixelFormat;

import android.graphics.Rect;

import android.graphics.Shader;

import android.graphics.drawable.Drawable;



/**

 * Created With Android Studio

 * User @47

 * Date 2014-07-28

 * Time 0:32

 */

public  class CircleDrawable extends Drawable {

    public static final String TAG = "CircleDrawable";



    protected final Paint paint;



    protected final int margin;

    protected final BitmapShader bitmapShader;

    protected float radius;

    protected Bitmap oBitmap;//原图

    public CircleDrawable(Bitmap bitmap){

        this(bitmap,0);

    }



    public CircleDrawable(Bitmap bitmap, int margin) {

        this.margin = margin;

        this.oBitmap = bitmap;

        bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

        paint = new Paint();

        paint.setAntiAlias(true);

        paint.setShader(bitmapShader);

    }



    @Override

    protected void onBoundsChange(Rect bounds) {

        super.onBoundsChange(bounds);

        computeBitmapShaderSize();

        computeRadius();



    }



    @Override

    public void draw(Canvas canvas) {

        Rect bounds = getBounds();//画一个圆圈

        canvas.drawCircle(bounds.width() / 2F,bounds.height() / 2F,radius,paint);

    }



    @Override

    public int getOpacity() {

        return PixelFormat.TRANSLUCENT;

    }



    @Override

    public void setAlpha(int alpha) {

        paint.setAlpha(alpha);

    }



    @Override

    public void setColorFilter(ColorFilter cf) {

        paint.setColorFilter(cf);

    }





    /**

     * 计算Bitmap shader 大小

     */

    public void computeBitmapShaderSize(){

        Rect bounds = getBounds();

        if(bounds == null) return;

        //选择缩放比较多的缩放,这样图片就不会有图片拉伸失衡

        Matrix matrix = new Matrix();

        float scaleX = bounds.width() / (float)oBitmap.getWidth();

        float scaleY = bounds.height() / (float)oBitmap.getHeight();

        float scale = scaleX > scaleY ? scaleX : scaleY;

        matrix.postScale(scale,scale);

        bitmapShader.setLocalMatrix(matrix);

    }



    /**

     * 计算半径的大小

     */

    public void computeRadius(){

        Rect bounds = getBounds();

        radius = bounds.width() < bounds.height() ?

                bounds.width() /2F - margin:

                bounds.height() / 2F - margin;

    }

}

接着就是CircleBitmapDisplayer 这个外壳

package auggie.library.displayers;



import android.graphics.Bitmap;



import com.nostra13.universalimageloader.core.assist.LoadedFrom;

import com.nostra13.universalimageloader.core.display.BitmapDisplayer;

import com.nostra13.universalimageloader.core.imageaware.ImageAware;

import com.nostra13.universalimageloader.core.imageaware.ImageViewAware;



/**

 * Created With Android Studio

 * User @47

 * Date 2014-07-27

 * Time 20:55

 * 显示原型图片的ImageLoader使用的显示器

 *

 */

public class CircleBitmapDisplayer implements BitmapDisplayer {



    protected  final int margin ;



    public CircleBitmapDisplayer() {

        this(0);

    }



    public CircleBitmapDisplayer(int margin) {

        this.margin = margin;

    }



    @Override

    public void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom) {

        if (!(imageAware instanceof ImageViewAware)) {

            throw new IllegalArgumentException("ImageAware should wrap ImageView. ImageViewAware is expected.");

        }



        imageAware.setImageDrawable(new CircleDrawable(bitmap, margin));

    }





}

这样着在ImageLoader 那里使用就可以了
package org.hangox.circleimageview;



import android.os.Bundle;

import android.support.v7.app.ActionBarActivity;

import android.widget.ImageView;



import com.nostra13.universalimageloader.core.DisplayImageOptions;

import com.nostra13.universalimageloader.core.ImageLoader;



import auggie.library.displayers.CircleBitmapDisplayer;





public class MainActivity extends ActionBarActivity {

    ImageView iViewCircleImageDisplayer;

    String imageUrl = "http://d.hiphotos.baidu" +

            ".com/image/pic/item/9358d109b3de9c8242a7de176e81800a18d84363.jpg";

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        iViewCircleImageDisplayer = (ImageView) findViewById(R.id.circle_image_displayer);

        ImageLoader.getInstance().displayImage(imageUrl,iViewCircleImageDisplayer,options);

//        BitmapDrawable bitmapDrawable = (BitmapDrawable) getResources().getDrawable(R.drawable.test_personal);

//        iViewCircleImageDisplayer.setImageDrawable(new CircleDrawable(bitmapDrawable.getBitmap()));

    }







    DisplayImageOptions options = new DisplayImageOptions.Builder()

            .cacheInMemory(true)

            .cacheOnDisk(true)

            .displayer(new CircleBitmapDisplayer())

            .build();





}

效果图:

image

总结:其实我想想做第一种的,结果我就做第二种的,发现第二种可以曲线实现第一种,就是把ImageView里面的Drawable

替换为CircleBitmapDislplayer ,其实这个我是写了的,在分开库的时候不知道为什么代码不见了。。。。。。。。

不过,这个库应该会继续更新,可能会用更多的显示效果

项目地址:https://github.com/L297084910/CircleImageView

你可能感兴趣的:(display)