分享一个超好用的圆形imageview自定义组件

来源:互联网 发布:大数据怎么可视化 编辑:程序博客网 时间:2024/06/05 22:45

近来无聊,写了一个圆形imageview组件

这组件的优点在于可以自动屏幕适配压缩图片,极大节省占用内存,并且可以在xml中动态设置图片模糊程度,要让图片以多高清晰度显示由你决定

效果如下:

这里写图片描述

从上到下分别设置了清晰度1, 4, 8,可以看出他们直接清晰度有很大区别

而从内存上来说:

直接显示原图内存是:

这里写图片描述

而用我的imageview压缩处理之后,内存是:

这里写图片描述

好啦,吹了这么多,话不多说,下面贴上源代码

首先,现在你的工程的res目录下的values创建一个attrs文件,内容如下:

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="circleImageView">        <attr name="imageSrc" format="reference"/>        <attr name="inSampleSize" format="integer"/>    </declare-styleable></resources>

上面那些是xml的属性,一个是获取图片id,相当于imageview的src,一个是设置图片清晰度,1是不变,越大只是清晰度越小

下面是自定义组件的源码:

package com.example.administrator.testmyidea.myTextView;import android.content.Context;import android.content.res.TypedArray;import android.graphics.*;import android.util.AttributeSet;import android.util.TypedValue;import android.view.View;import com.example.administrator.testmyidea.R;public class circleImageView extends View{    private Paint mPaint;    private Bitmap imageBitmap;    private float circleRadio;    private int imageResourceId;    private int mInSampleSize=1;    private int mWidth;    public circleImageView(Context context,int width) {        super(context);        mPaint=new Paint();        mWidth=width;    }    public circleImageView(Context context, AttributeSet attrs) {        super(context, attrs);        System.out.println("圆的历程"+"circleImageView");        mPaint=new Paint();        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.circleImageView, 0, 0);        System.out.println("imageResourceId="+imageResourceId);        int n = a.getIndexCount();        for (int i = 0; i < n; i++)        {            int attr = a.getIndex(i);            switch (attr)            {                //获取图片id                case R.styleable.circleImageView_imageSrc:                    imageResourceId=a.getResourceId(attr,R.drawable.moren);                    break;                //获取图片清晰度设置                case R.styleable.circleImageView_inSampleSize:                    mInSampleSize=a.getInteger(attr,1);                    break;            }        }        a.recycle();        if(imageResourceId==0)imageResourceId=R.drawable.moren;    }    @Override    protected void onDraw(Canvas canvas) {        System.out.println("圆的历程"+"onDraw");        canvas.drawBitmap(imageBitmap,0,0,mPaint);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        mWidth=widthSize;        if(imageBitmap==null||imageBitmap.isRecycled()){            System.out.println("圆的历程"+"imageBitmap");            imageBitmap=getCircle(getSampleBitmap2(imageResourceId,widthSize));        }        setMeasuredDimension(widthSize, heightSize);        System.out.println("圆的历程"+"onMeasure");    }    //动态设置图片    public void setImageid(int imageid){        System.out.println("圆的历程"+"setImageid");        if(mWidth==0)imageResourceId=imageid;        else{            imageResourceId=imageid;            if(!imageBitmap.isRecycled()){                imageBitmap.recycle();                imageBitmap=null;            }            imageBitmap=getCircle(getSampleBitmap2(imageResourceId,mWidth));            postInvalidate();        }    }    //动态设置图片清晰度    public void setSimpleSize(int size){        System.out.println("圆的历程"+"setSimpleSize");        if(mWidth==0)mInSampleSize=size;        else{            mInSampleSize=size;            if(!imageBitmap.isRecycled()){                imageBitmap.recycle();                imageBitmap=null;            }            imageBitmap=getCircle(getSampleBitmap2(imageResourceId,mWidth));            postInvalidate();        }    }    public Bitmap getCircle(Bitmap bitmap){        //circleRadio圆形图片的半径        float circleRadio;        //bitmapSize图片的尺寸,也就是圆的直径,正方形图片的边长        int bitmapSize;        if(bitmap.getHeight()>bitmap.getWidth()){            circleRadio=bitmap.getWidth()/2;            bitmapSize=bitmap.getWidth();        }else{            circleRadio=bitmap.getHeight()/2;            bitmapSize=bitmap.getHeight();        }        //创建一张新的bitmap,跟传入图片一样宽的正方形bitmap,        Bitmap b=Bitmap.createBitmap(bitmapSize,bitmapSize, Bitmap.Config.ARGB_8888);        //将图片密度修改为上面那张的图片密度        b.setDensity(bitmap.getDensity());        //初始化画布,并将刚才创建的bitmap给这画布,让画布画在这bitmap上面        Canvas canvas=new Canvas(b);        //初始化画笔        Paint p=new Paint();        //在画布中画一个等宽的圆        canvas.drawCircle(circleRadio,circleRadio,circleRadio,p);        //设置画笔属性,让画笔只在哪圆圈中画画,关于画笔属性,可以百度一下,很多,但是非常有用        p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));        canvas.drawBitmap(bitmap,0,0,p);        return  b;    }    /**     * 获取特定大小缩略图     * @param imageid 图片资源id     * @param size 你想要获取的图片大小尺寸     * @return     */    public Bitmap getSampleBitmap2(int imageid,int size){        BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds=true;        BitmapFactory.decodeResource(getResources(),imageid,options);        options.inPreferredConfig = Bitmap.Config.ARGB_8888;        options.inSampleSize= calculateInSampleSize(options,size)*mInSampleSize;        //设置图片可以缩小        options.inScaled = true;        int calsize=options.outHeight>options.outWidth?options.outWidth:options.outHeight;        /**         * 计算图片缩小的目标密度,在这里说一下,有一条公式:         * 输出图片的宽高= (原图片的宽高 * (inTargetDensity / inDensity)) / inSampleSize         * 一般来说,图片的options.inDensity默认为160         * 所以inTargetDensity计算公式为:(希望输出的宽高*options.inDensity)/(原来图片的宽高/options.inSampleSize)         */        options.inTargetDensity =(size*options.inDensity)/(calsize/options.inSampleSize);        options.inJustDecodeBounds = false;        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),imageid,options);        circleRadio=bitmap.getWidth()/2;        return bitmap;    }    //谷歌源码里面的计算simplesize方法,    public int calculateInSampleSize(BitmapFactory.Options options,                                     int size) {        int reqWidth,reqHeight;        // Raw height and width of image        final int height = options.outHeight;        final int width = options.outWidth;        if(options.outHeight>options.outWidth){            reqWidth=size;            reqHeight=size*options.outHeight/options.outWidth;        }else{            reqWidth=size*options.outWidth/options.outHeight;            reqHeight=size;        }        int inSampleSize = 1;        if (height > reqHeight || width > reqWidth) {            final int halfHeight = height / 2;            final int halfWidth = width / 2;            // Calculate the largest inSampleSize value that is a power of 2 and            // keeps both            // height and width larger than the requested height and width.            while ((halfHeight / inSampleSize) > reqHeight                    && (halfWidth / inSampleSize) > reqWidth) {                inSampleSize *= 2;            }        }        return inSampleSize;    }}

然后你用的时候直接这样用就好了:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout        xmlns:android="http://schemas.android.com/apk/res/android"        xmlns:tools="http://schemas.android.com/tools"        xmlns:luo="http://schemas.android.com/apk/res-auto"        android:layout_width="match_parent"        android:layout_height="match_parent"        tools:context="com.example.administrator.testmyidea.MainActivity">    <com.example.administrator.testmyidea.myTextView.circleImageView            luo:imageSrc="@drawable/timg"            luo:inSampleSize="1"            android:layout_width="150dp"            android:layout_height="150dp"/></RelativeLayout>

对了,记得在你的xml里面加上自定义组件的命名空间,如果你用的开发工具是androidStudo,那么要加

xmlns:luo="http://schemas.android.com/apk/res-auto"

如同我上面一样

eclipse的话,那就比较恶心了,得动态加载到包名,格式如同下面

//其中com.xxx是你的包名xmlns:luo="http://schemas.android.com/apk/res/com.xxx"

好啦,然后就可以使用这个组件啦~~~

public class MainActivity extends Activity {    circleImageView circle;    int size=1;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        findViewById(R.id.go).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                circle.setSimpleSize(size++);            }        });        circle=(circleImageView)findViewById(ll);        circle.setImageid(R.drawable.touxiang);    }}
原创粉丝点击