分享一个超好用的圆形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); }}
阅读全文
0 0
- 分享一个超好用的圆形imageview自定义组件
- 自定义一个圆形ImageView组件
- 自定义圆形的Imageview
- 自定义圆形的ImageView
- 自定义圆形的ImageVIew
- (原创)分享一个实用的圆形ImageView
- imageview的自定义圆形图片
- android 自定义圆形的ImageView
- 圆形头像以及一些常见需求形状自定义ImageView组件
- 圆形自定义ImageView的简单制作
- android中自定义的圆形ImageView
- Glide加载自定义的圆形Imageview
- 自定义带 vip 标识的 圆形头像(圆形ImageView)
- 圆形imageview自定义
- 自定义圆形ImageView
- 自定义android圆形ImageView
- android自定义圆形imageview
- 自定义圆形ImageView(一)
- 集合
- ubuntu下两个gcc版本切换
- Elasticsearch实践
- Qml圆形进度按钮
- Android开源控件笔记
- 分享一个超好用的圆形imageview自定义组件
- artTemplate的函数使用
- linux命令小记(grep、awk、sed)
- maven添加jra包
- Executor框架学习
- mybatis模糊查询like使用
- Qt显示中文
- Java NIO
- 异常和常用Api